<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <title>Open Screen Protocol</title>
<style data-fill-with="stylesheet">/******************************************************************************
 *                   Style sheet for the W3C specifications                   *
 *
 * Special classes handled by this style sheet include:
 *
 * Indices
 *   - .toc for the Table of Contents (<ol class="toc">)
 *     + <span class="secno"> for the section numbers
 *   - #toc for the Table of Contents (<nav id="toc">)
 *   - ul.index for Indices (<a href="#ref">term</a><span>, in §N.M</span>)
 *   - table.index for Index Tables (e.g. for properties or elements)
 *
 * Structural Markup
 *   - table.data for general data tables
 *     -> use 'scope' attribute, <colgroup>, <thead>, and <tbody> for best results !
 *     -> use <table class='complex data'> for extra-complex tables
 *     -> use <td class='long'> for paragraph-length cell content
 *     -> use <td class='pre'> when manual line breaks/indentation would help readability
 *   - dl.switch for switch statements
 *   - ol.algorithm for algorithms (helps to visualize nesting)
 *   - .figure and .caption (HTML4) and figure and figcaption (HTML5)
 *     -> .sidefigure for right-floated figures
 *   - ins/del
 *
 * Code
 *   - pre and code
 *
 * Special Sections
 *   - .note       for informative notes             (div, p, span, aside, details)
 *   - .example    for informative examples          (div, p, pre, span)
 *   - .issue      for issues                        (div, p, span)
 *   - .assertion  for assertions                    (div, p, span)
 *   - .advisement for loud normative statements     (div, p, strong)
 *   - .annoying-warning for spec obsoletion notices (div, aside, details)
 *
 * Definition Boxes
 *   - pre.def   for WebIDL definitions
 *   - table.def for tables that define other entities (e.g. CSS properties)
 *   - dl.def    for definition lists that define other entitles (e.g. HTML elements)
 *
 * Numbering
 *   - .secno for section numbers in .toc and headings (<span class='secno'>3.2</span>)
 *   - .marker for source-inserted example/figure/issue numbers (<span class='marker'>Issue 4</span>)
 *   - ::before styled for CSS-generated issue/example/figure numbers:
 *     -> Documents wishing to use this only need to add
 *        figcaption::before,
 *        .caption::before { content: "Figure "  counter(figure) " ";  }
 *        .example::before { content: "Example " counter(example) " "; }
 *        .issue::before   { content: "Issue "   counter(issue) " ";   }
 *
 * Header Stuff (ignore, just don't conflict with these classes)
 *   - .head for the header
 *   - .copyright for the copyright
 *
 * Miscellaneous
 *   - .overlarge for things that should be as wide as possible, even if
 *     that overflows the body text area. This can be used on an item or
 *     on its container, depending on the effect desired.
 *     Note that this styling basically doesn't help at all when printing,
 *     since A4 paper isn't much wider than the max-width here.
 *     It's better to design things to fit into a narrower measure if possible.
 *   - js-added ToC jump links (see fixup.js)
 *
 ******************************************************************************/

/******************************************************************************/
/*                                   Body                                     */
/******************************************************************************/

	body {
		counter-reset: example figure issue;

		/* Layout */
		max-width: 50em;               /* limit line length to 50em for readability   */
		margin: 0 auto;                /* center text within page                     */
		padding: 1.6em 1.5em 2em 50px; /* assume 16px font size for downlevel clients */
		padding: 1.6em 1.5em 2em calc(26px + 1.5em); /* leave space for status flag     */

		/* Typography */
		line-height: 1.5;
		font-family: sans-serif;
		widows: 2;
		orphans: 2;
		word-wrap: break-word;
		overflow-wrap: break-word;
		hyphens: auto;

		/* Colors */
		color: black;
		background: white top left fixed no-repeat;
		background-size: 25px auto;
	}


/******************************************************************************/
/*                         Front Matter & Navigation                          */
/******************************************************************************/

/** Header ********************************************************************/

	div.head { margin-bottom: 1em }
	div.head hr { border-style: solid; }

	div.head h1 {
		font-weight: bold;
		margin: 0 0 .1em;
		font-size: 220%;
	}

	div.head h2 { margin-bottom: 1.5em;}

/** W3C Logo ******************************************************************/

	.head .logo {
		float: right;
		margin: 0.4rem 0 0.2rem .4rem;
	}

	.head img[src*="logos/W3C"] {
		display: block;
		border: solid #1a5e9a;
		border-width: .65rem .7rem .6rem;
		border-radius: .4rem;
		background: #1a5e9a;
		color: white;
		font-weight: bold;
	}

	.head a:hover > img[src*="logos/W3C"],
	.head a:focus > img[src*="logos/W3C"] {
		opacity: .8;
	}

	.head a:active > img[src*="logos/W3C"] {
		background: #c00;
		border-color: #c00;
	}

	/* see also additional rules in Link Styling section */

/** Copyright *****************************************************************/

	p.copyright,
	p.copyright small { font-size: small }

/** Back to Top / ToC Toggle **************************************************/

	@media print {
		#toc-nav {
			display: none;
		}
	}
	@media not print {
		#toc-nav {
			position: fixed;
			z-index: 2;
			bottom: 0; left: 0;
			margin: 0;
			min-width: 1.33em;
			border-top-right-radius: 2rem;
			box-shadow: 0 0 2px;
			font-size: 1.5em;
			color: black;
		}
		#toc-nav > a {
			display: block;
			white-space: nowrap;

			height: 1.33em;
			padding: .1em 0.3em;
			margin: 0;

			background: white;
			box-shadow: 0 0 2px;
			border: none;
			border-top-right-radius: 1.33em;
			background: white;
		}
		#toc-nav > #toc-jump {
			padding-bottom: 2em;
			margin-bottom: -1.9em;
		}

		#toc-nav > a:hover,
		#toc-nav > a:focus {
			background: #f8f8f8;
		}
		#toc-nav > a:not(:hover):not(:focus) {
			color: #707070;
		}

		/* statusbar gets in the way on keyboard focus; remove once browsers fix */
		#toc-nav > a[href="#toc"]:not(:hover):focus:last-child {
			padding-bottom: 1.5rem;
		}

		#toc-nav:not(:hover) > a:not(:focus) > span + span {
			/* Ideally this uses :focus-within on #toc-nav */
			display: none;
		}
		#toc-nav > a > span + span {
			padding-right: 0.2em;
		}

		#toc-toggle-inline {
			vertical-align: 0.05em;
			font-size: 80%;
			color: gray;
			color: hsla(203,20%,40%,.7);
			border-style: none;
			background: transparent;
			position: relative;
		}
		#toc-toggle-inline:hover:not(:active),
		#toc-toggle-inline:focus:not(:active) {
			text-shadow: 1px 1px silver;
			top: -1px;
			left: -1px;
		}

		#toc-nav :active {
			color: #C00;
		}
	}

/** ToC Sidebar ***************************************************************/

	/* Floating sidebar */
	@media screen {
		body.toc-sidebar #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			max-width: 80%;
			max-width: calc(100% - 2em - 26px);
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body.toc-sidebar #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}
		body.toc-sidebar #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	/* Hide main scroller when only the ToC is visible anyway */
	@media screen and (max-width: 28em) {
		body.toc-sidebar {
			overflow: hidden;
		}
	}

	/* Sidebar with its own space */
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) #toc {
			position: fixed;
			top: 0; bottom: 0;
			left: 0;
			width: 23.5em;
			overflow: auto;
			padding: 0 1em;
			padding-left: 42px;
			padding-left: calc(1em + 26px);
			background: inherit;
			background-color: #f7f8f9;
			z-index: 1;
			box-shadow: -.1em 0 .25em rgba(0,0,0,.1) inset;
		}
		body:not(.toc-inline) #toc h2 {
			margin-top: .8rem;
			font-variant: small-caps;
			font-variant: all-small-caps;
			text-transform: lowercase;
			font-weight: bold;
			color: gray;
			color: hsla(203,20%,40%,.7);
		}

		body:not(.toc-inline) {
			padding-left: 29em;
		}
		/* See also Overflow section at the bottom */

		body:not(.toc-inline) #toc-jump:not(:focus) {
			width: 0;
			height: 0;
			padding: 0;
			position: absolute;
			overflow: hidden;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) {
			margin: 0 4em;
		}
	}

/******************************************************************************/
/*                                Sectioning                                  */
/******************************************************************************/

/** Headings ******************************************************************/

	h1, h2, h3, h4, h5, h6, dt {
		page-break-after: avoid;
		page-break-inside: avoid;
		font: 100% sans-serif;   /* Reset all font styling to clear out UA styles */
		font-family: inherit;    /* Inherit the font family. */
		line-height: 1.2;        /* Keep wrapped headings compact */
		hyphens: manual;         /* Hyphenated headings look weird */
	}

	h2, h3, h4, h5, h6 {
		margin-top: 3rem;
	}

	h1, h2, h3 {
		color: #005A9C;
		background: transparent;
	}

	h1 { font-size: 170%; }
	h2 { font-size: 140%; }
	h3 { font-size: 120%; }
	h4 { font-weight: bold; }
	h5 { font-style: italic; }
	h6 { font-variant: small-caps; }
	dt { font-weight: bold; }

/** Subheadings ***************************************************************/

	h1 + h2,
	#subtitle {
		/* #subtitle is a subtitle in an H2 under the H1 */
		margin-top: 0;
	}
	h2 + h3,
	h3 + h4,
	h4 + h5,
	h5 + h6 {
		margin-top: 1.2em; /* = 1 x line-height */
	}

/** Section divider ***********************************************************/

	:not(.head) > hr {
		font-size: 1.5em;
		text-align: center;
		margin: 1em auto;
		height: auto;
		border: transparent solid 0;
		background: transparent;
	}
	:not(.head) > hr::before {
		content: "\2727\2003\2003\2727\2003\2003\2727";
	}

/******************************************************************************/
/*                            Paragraphs and Lists                            */
/******************************************************************************/

	p {
		margin: 1em 0;
	}

	dd > p:first-child,
	li > p:first-child {
		margin-top: 0;
	}

	ul, ol {
		margin-left: 0;
		padding-left: 2em;
	}

	li {
		margin: 0.25em 0 0.5em;
		padding: 0;
	}

	dl dd {
		margin: 0 0 .5em 2em;
	}

	.head dd + dd { /* compact for header */
		margin-top: -.5em;
	}

	/* Style for algorithms */
	ol.algorithm ol:not(.algorithm),
	.algorithm > ol ol:not(.algorithm) {
	 border-left: 0.5em solid #DEF;
	}

	/* Put nice boxes around each algorithm. */
	[data-algorithm]:not(.heading) {
	  padding: .5em;
	  border: thin solid #ddd; border-radius: .5em;
	  margin: .5em calc(-0.5em - 1px);
	}
	[data-algorithm]:not(.heading) > :first-child {
	  margin-top: 0;
	}
	[data-algorithm]:not(.heading) > :last-child {
	  margin-bottom: 0;
	}

	/* Style for switch/case <dl>s */
	dl.switch > dd > ol.only,
	dl.switch > dd > .only > ol {
	 margin-left: 0;
	}
	dl.switch > dd > ol.algorithm,
	dl.switch > dd > .algorithm > ol {
	 margin-left: -2em;
	}
	dl.switch {
	 padding-left: 2em;
	}
	dl.switch > dt {
	 text-indent: -1.5em;
	 margin-top: 1em;
	}
	dl.switch > dt + dt {
	 margin-top: 0;
	}
	dl.switch > dt::before {
	 content: '\21AA';
	 padding: 0 0.5em 0 0;
	 display: inline-block;
	 width: 1em;
	 text-align: right;
	 line-height: 0.5em;
	}

/** Terminology Markup ********************************************************/


/******************************************************************************/
/*                                 Inline Markup                              */
/******************************************************************************/

/** Terminology Markup ********************************************************/
	dfn   { /* Defining instance */
		font-weight: bolder;
	}
	a > i { /* Instance of term */
		font-style: normal;
	}
	dt dfn code, code.idl {
		font-size: medium;
	}
	dfn var {
		font-style: normal;
	}

/** Change Marking ************************************************************/

	del { color: red;  text-decoration: line-through; }
	ins { color: #080; text-decoration: underline;    }

/** Miscellaneous improvements to inline formatting ***************************/

	sup {
		vertical-align: super;
		font-size: 80%
	}

/******************************************************************************/
/*                                    Code                                    */
/******************************************************************************/

/** General monospace/pre rules ***********************************************/

	pre, code, samp {
		font-family: Menlo, Consolas, "DejaVu Sans Mono", Monaco, monospace;
		font-size: .9em;
		page-break-inside: avoid;
		hyphens: none;
		text-transform: none;
	}
	pre code,
	code code {
		font-size: 100%;
	}

	pre {
		margin-top: 1em;
		margin-bottom: 1em;
		overflow: auto;
	}

/** Inline Code fragments *****************************************************/

  /* Do something nice. */

/******************************************************************************/
/*                                    Links                                   */
/******************************************************************************/

/** General Hyperlinks ********************************************************/

	/* We hyperlink a lot, so make it less intrusive */
	a[href] {
		color: #034575;
		text-decoration: none;
		border-bottom: 1px solid #707070;
		/* Need a bit of extending for it to look okay */
		padding: 0 1px 0;
		margin: 0 -1px 0;
	}
	a:visited {
		border-bottom-color: #BBB;
	}

	/* Use distinguishing colors when user is interacting with the link */
	a[href]:focus,
	a[href]:hover {
		background: #f8f8f8;
		background: rgba(75%, 75%, 75%, .25);
		border-bottom-width: 3px;
		margin-bottom: -2px;
	}
	a[href]:active {
		color: #C00;
		border-color: #C00;
	}

	/* Backout above styling for W3C logo */
	.head .logo,
	.head .logo a {
		border: none;
		text-decoration: none;
		background: transparent;
	}

/******************************************************************************/
/*                                    Images                                  */
/******************************************************************************/

	img {
		border-style: none;
	}

	/* For autogen numbers, add
	   .caption::before, figcaption::before { content: "Figure " counter(figure) ". "; }
	*/

	figure, .figure, .sidefigure {
		page-break-inside: avoid;
		text-align: center;
		margin: 2.5em 0;
	}
	.figure img,    .sidefigure img,    figure img,
	.figure object, .sidefigure object, figure object {
		max-width: 100%;
		margin: auto;
	}
	.figure pre, .sidefigure pre, figure pre {
		text-align: left;
		display: table;
		margin: 1em auto;
	}
	.figure table, figure table {
		margin: auto;
	}
	@media screen and (min-width: 20em) {
		.sidefigure {
			float: right;
			width: 50%;
			margin: 0 0 0.5em 0.5em
		}
	}
	.caption, figcaption, caption {
		font-style: italic;
		font-size: 90%;
	}
	.caption::before, figcaption::before, figcaption > .marker {
		font-weight: bold;
	}
	.caption, figcaption {
		counter-increment: figure;
	}

	/* DL list is indented 2em, but figure inside it is not */
	dd > .figure, dd > figure { margin-left: -2em }

/******************************************************************************/
/*                             Colored Boxes                                  */
/******************************************************************************/

	.issue, .note, .example, .assertion, .advisement, blockquote {
		padding: .5em;
		border: .5em;
		border-left-style: solid;
		page-break-inside: avoid;
	}
	span.issue, span.note {
		padding: .1em .5em .15em;
		border-right-style: solid;
	}

	.issue,
	.note,
	.example,
	.advisement,
	.assertion,
	blockquote {
		margin: 1em auto;
	}
	.note  > p:first-child,
	.issue > p:first-child,
	blockquote > :first-child {
		margin-top: 0;
	}
	blockquote > :last-child {
		margin-bottom: 0;
	}

/** Blockquotes ***************************************************************/

	blockquote {
		border-color: silver;
	}

/** Open issue ****************************************************************/

	.issue {
		border-color: #E05252;
		background: #FBE9E9;
		counter-increment: issue;
		overflow: auto;
	}
	.issue::before, .issue > .marker {
		text-transform: uppercase;
		color: #AE1E1E;
		padding-right: 1em;
		text-transform: uppercase;
	}
	/* Add .issue::before { content: "Issue " counter(issue) " "; } for autogen numbers,
	   or use class="marker" to mark up the issue number in source. */

/** Example *******************************************************************/

	.example {
		border-color: #E0CB52;
		background: #FCFAEE;
		counter-increment: example;
		overflow: auto;
		clear: both;
	}
	.example::before, .example > .marker {
		text-transform: uppercase;
		color: #827017;
		min-width: 7.5em;
		display: block;
	}
	/* Add .example::before { content: "Example " counter(example) " "; } for autogen numbers,
	   or use class="marker" to mark up the example number in source. */

/** Non-normative Note ********************************************************/

	.note {
		border-color: #52E052;
		background: #E9FBE9;
		overflow: auto;
	}

	.note::before, .note > .marker,
	details.note > summary::before,
	details.note > summary > .marker {
		text-transform: uppercase;
		display: block;
		color: hsl(120, 70%, 30%);
	}
	/* Add .note::before { content: "Note"; } for autogen label,
	   or use class="marker" to mark up the label in source. */

	details.note > summary {
		display: block;
		color: hsl(120, 70%, 30%);
	}
	details.note[open] > summary {
		border-bottom: 1px silver solid;
	}

/** Assertion Box *************************************************************/
	/*  for assertions in algorithms */

	.assertion {
		border-color: #AAA;
		background: #EEE;
	}

/** Advisement Box ************************************************************/
	/*  for attention-grabbing normative statements */

	.advisement {
		border-color: orange;
		border-style: none solid;
		background: #FFEECC;
	}
	strong.advisement {
		display: block;
		text-align: center;
	}
	.advisement > .marker {
		color: #B35F00;
	}

/** Spec Obsoletion Notice ****************************************************/
	/* obnoxious obsoletion notice for older/abandoned specs. */

	details {
		display: block;
	}
	summary {
		font-weight: bolder;
	}

	.annoying-warning:not(details),
	details.annoying-warning:not([open]) > summary,
	details.annoying-warning[open] {
		background: #fdd;
		color: red;
		font-weight: bold;
		padding: .75em 1em;
		border: thick red;
		border-style: solid;
		border-radius: 1em;
	}
	.annoying-warning :last-child {
		margin-bottom: 0;
	}

@media not print {
	details.annoying-warning[open] {
		position: fixed;
		left: 1em;
		right: 1em;
		bottom: 1em;
		z-index: 1000;
	}
}

	details.annoying-warning:not([open]) > summary {
		text-align: center;
	}

/** Entity Definition Boxes ***************************************************/

	.def {
		padding: .5em 1em;
		background: #DEF;
		margin: 1.2em 0;
		border-left: 0.5em solid #8CCBF2;
	}

/******************************************************************************/
/*                                    Tables                                  */
/******************************************************************************/

	th, td {
		text-align: left;
		text-align: start;
	}

/** Property/Descriptor Definition Tables *************************************/

	table.def {
		/* inherits .def box styling, see above */
		width: 100%;
		border-spacing: 0;
	}

	table.def td,
	table.def th {
		padding: 0.5em;
		vertical-align: baseline;
		border-bottom: 1px solid #bbd7e9;
	}

	table.def > tbody > tr:last-child th,
	table.def > tbody > tr:last-child td {
		border-bottom: 0;
	}

	table.def th {
		font-style: italic;
		font-weight: normal;
		padding-left: 1em;
		width: 3em;
	}

	/* For when values are extra-complex and need formatting for readability */
	table td.pre {
		white-space: pre-wrap;
	}

	/* A footnote at the bottom of a def table */
	table.def           td.footnote {
		padding-top: 0.6em;
	}
	table.def           td.footnote::before {
		content: " ";
		display: block;
		height: 0.6em;
		width: 4em;
		border-top: thin solid;
	}

/** Data tables (and properly marked-up index tables) *************************/
	/*
		 <table class="data"> highlights structural relationships in a table
		 when correct markup is used (e.g. thead/tbody, th vs. td, scope attribute)

		 Use class="complex data" for particularly complicated tables --
		 (This will draw more lines: busier, but clearer.)

		 Use class="long" on table cells with paragraph-like contents
		 (This will adjust text alignment accordingly.)
		 Alternately use class="longlastcol" on tables, to have the last column assume "long".
	*/

	table {
		word-wrap: normal;
		overflow-wrap: normal;
		hyphens: manual;
	}

	table.data,
	table.index {
		margin: 1em auto;
		border-collapse: collapse;
		border: hidden;
		width: 100%;
	}
	table.data caption,
	table.index caption {
		max-width: 50em;
		margin: 0 auto 1em;
	}

	table.data td,  table.data th,
	table.index td, table.index th {
		padding: 0.5em 1em;
		border-width: 1px;
		border-color: silver;
		border-top-style: solid;
	}

	table.data thead td:empty {
		padding: 0;
		border: 0;
	}

	table.data  thead,
	table.index thead,
	table.data  tbody,
	table.index tbody {
		border-bottom: 2px solid;
	}

	table.data colgroup,
	table.index colgroup {
		border-left: 2px solid;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		border-right: 2px solid;
		border-top: 1px solid silver;
		padding-right: 1em;
	}

	table.data th[colspan],
	table.data td[colspan] {
		text-align: center;
	}

	table.complex.data th,
	table.complex.data td {
		border: 1px solid silver;
		text-align: center;
	}

	table.data.longlastcol td:last-child,
	table.data td.long {
	 vertical-align: baseline;
	 text-align: left;
	}

	table.data img {
		vertical-align: middle;
	}


/*
Alternate table alignment rules

	table.data,
	table.index {
		text-align: center;
	}

	table.data  thead th[scope="row"],
	table.index thead th[scope="row"] {
		text-align: right;
	}

	table.data  tbody th:first-child,
	table.index tbody th:first-child  {
		text-align: right;
	}

Possible extra rowspan handling

	table.data  tbody th[rowspan]:not([rowspan='1']),
	table.index tbody th[rowspan]:not([rowspan='1']),
	table.data  tbody td[rowspan]:not([rowspan='1']),
	table.index tbody td[rowspan]:not([rowspan='1']) {
		border-left: 1px solid silver;
	}

	table.data  tbody th[rowspan]:first-child,
	table.index tbody th[rowspan]:first-child,
	table.data  tbody td[rowspan]:first-child,
	table.index tbody td[rowspan]:first-child{
		border-left: 0;
		border-right: 1px solid silver;
	}
*/

/******************************************************************************/
/*                                  Indices                                   */
/******************************************************************************/


/** Table of Contents *********************************************************/

	.toc a {
		/* More spacing; use padding to make it part of the click target. */
		padding-top: 0.1rem;
		/* Larger, more consistently-sized click target */
		display: block;
		/* Reverse color scheme */
		color: black;
		border-color: #3980B5;
		border-bottom-width: 3px !important;
		margin-bottom: 0px !important;
	}
	.toc a:visited {
		border-color: #054572;
	}
	.toc a:not(:focus):not(:hover) {
		/* Allow colors to cascade through from link styling */
		border-bottom-color: transparent;
	}

	.toc, .toc ol, .toc ul, .toc li {
		list-style: none; /* Numbers must be inlined into source */
		/* because generated content isn't search/selectable and markers can't do multilevel yet */
		margin:  0;
		padding: 0;
		line-height: 1.1rem; /* consistent spacing */
	}

	/* ToC not indented until third level, but font style & margins show hierarchy */
	.toc > li             { font-weight: bold;   }
	.toc > li li          { font-weight: normal; }
	.toc > li li li       { font-size:   95%;    }
	.toc > li li li li    { font-size:   90%;    }
	.toc > li li li li .secno { font-size: 85%; }
	.toc > li li li li li { font-size:   85%;    }
	.toc > li li li li li .secno { font-size: 100%; }

	/* @supports not (display:grid) { */
		.toc > li             { margin: 1.5rem 0;    }
		.toc > li li          { margin: 0.3rem 0;    }
		.toc > li li li       { margin-left: 2rem;   }

		/* Section numbers in a column of their own */
		.toc .secno {
			float: left;
			width: 4rem;
			white-space: nowrap;
		}

		.toc li {
			clear: both;
		}

		:not(li) > .toc              { margin-left:  5rem; }
		.toc .secno                  { margin-left: -5rem; }
		.toc > li li li .secno       { margin-left: -7rem; }
		.toc > li li li li .secno    { margin-left: -9rem; }
		.toc > li li li li li .secno { margin-left: -11rem; }

		/* Tighten up indentation in narrow ToCs */
		@media (max-width: 30em) {
			:not(li) > .toc              { margin-left:  4rem; }
			.toc .secno                  { margin-left: -4rem; }
			.toc > li li li              { margin-left:  1rem; }
			.toc > li li li .secno       { margin-left: -5rem; }
			.toc > li li li li .secno    { margin-left: -6rem; }
			.toc > li li li li li .secno { margin-left: -7rem; }
		}
	/* } */

	@supports (display:grid) and (display:contents) {
		/* Use #toc over .toc to override non-@supports rules. */
		#toc {
			display: grid;
			align-content: start;
			grid-template-columns: auto 1fr;
			grid-column-gap: 1rem;
			column-gap: 1rem;
			grid-row-gap: .6rem;
			row-gap: .6rem;
		}
		#toc h2 {
			grid-column: 1 / -1;
			margin-bottom: 0;
		}
		#toc ol,
		#toc li,
		#toc a {
			display: contents;
			/* Switch <a> to subgrid when supported */
		}
		#toc span {
			margin: 0;
		}
		#toc > .toc > li > a > span {
			/* The spans of the top-level list,
			   comprising the first items of each top-level section. */
			margin-top: 1.1rem;
		}
		#toc#toc .secno { /* Ugh, need more specificity to override base.css */
			grid-column: 1;
			width: auto;
			margin-left: 0;
		}
		#toc .content {
			grid-column: 2;
			width: auto;
			margin-right: 1rem;
		}
		#toc .content:hover {
			background: rgba(75%, 75%, 75%, .25);
			border-bottom: 3px solid #054572;
			margin-bottom: -3px;
		}
		#toc li li li .content {
			margin-left: 1rem;
		}
		#toc li li li li .content {
			margin-left: 2rem;
		}
	}


/** Index *********************************************************************/

	/* Index Lists: Layout */
	ul.index       { margin-left: 0; columns: 15em; text-indent: 1em hanging; }
	ul.index li    { margin-left: 0; list-style: none; break-inside: avoid; }
	ul.index li li { margin-left: 1em }
	ul.index dl    { margin-top: 0; }
	ul.index dt    { margin: .2em 0 .2em 20px;}
	ul.index dd    { margin: .2em 0 .2em 40px;}
	/* Index Lists: Typography */
	ul.index ul,
	ul.index dl { font-size: smaller; }
	@media not print {
		ul.index li span {
			white-space: nowrap;
			color: transparent; }
		ul.index li a:hover + span,
		ul.index li a:focus + span {
			color: #707070;
		}
	}

/** Index Tables *****************************************************/
	/* See also the data table styling section, which this effectively subclasses */

	table.index {
		font-size: small;
		border-collapse: collapse;
		border-spacing: 0;
		text-align: left;
		margin: 1em 0;
	}

	table.index td,
	table.index th {
		padding: 0.4em;
	}

	table.index tr:hover td:not([rowspan]),
	table.index tr:hover th:not([rowspan]) {
		background: #f7f8f9;
	}

	/* The link in the first column in the property table (formerly a TD) */
	table.index th:first-child a {
		font-weight: bold;
	}

/******************************************************************************/
/*                                    Print                                   */
/******************************************************************************/

	@media print {
		/* Pages have their own margins. */
		html {
			margin: 0;
		}
		/* Serif for print. */
		body {
			font-family: serif;
		}
	}
	@page {
		margin: 1.5cm 1.1cm;
	}

/******************************************************************************/
/*                                    Legacy                                  */
/******************************************************************************/

	/* This rule is inherited from past style sheets. No idea what it's for. */
	.hide { display: none }



/******************************************************************************/
/*                             Overflow Control                               */
/******************************************************************************/

	.figure .caption, .sidefigure .caption, figcaption {
		/* in case figure is overlarge, limit caption to 50em */
		max-width: 50rem;
		margin-left: auto;
		margin-right: auto;
	}
	.overlarge {
		/* Magic to create good table positioning:
		   "content column" is 50ems wide at max; less on smaller screens.
		   Extra space (after ToC + content) is empty on the right.

		   1. When table < content column, centers table in column.
		   2. When content < table < available, left-aligns.
		   3. When table > available, fills available + scroll bar.
		*/ 
		display: grid;
		grid-template-columns: minmax(0, 50em);
	}
	.overlarge > table {
		/* limit preferred width of table */
		max-width: 50em;
		margin-left: auto;
		margin-right: auto;
	}

	@media (min-width: 55em) {
		.overlarge {
			margin-right: calc(13px + 26.5rem - 50vw);
			max-width: none;
		}
	}
	@media screen and (min-width: 78em) {
		body:not(.toc-inline) .overlarge {
			/* 30.5em body padding 50em content area */
			margin-right: calc(40em - 50vw) !important;
		}
	}
	@media screen and (min-width: 90em) {
		body:not(.toc-inline) .overlarge {
			/* 4em html margin 30.5em body padding 50em content area */
			margin-right: calc(84.5em - 100vw) !important;
		}
	}

	@media not print {
		.overlarge {
			overflow-x: auto;
			/* See Lea Verou's explanation background-attachment:
			 * http://lea.verou.me/2012/04/background-attachment-local/
			 *
			background: top left  / 4em 100% linear-gradient(to right,  #ffffff, rgba(255, 255, 255, 0)) local,
			            top right / 4em 100% linear-gradient(to left, #ffffff, rgba(255, 255, 255, 0)) local,
			            top left  / 1em 100% linear-gradient(to right,  #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            top right / 1em 100% linear-gradient(to left, #c3c3c5, rgba(195, 195, 197, 0)) scroll,
			            white;
			background-repeat: no-repeat;
			*/
		}
	}
</style>
  <link href="https://www.w3.org/StyleSheets/TR/2016/W3C-ED" rel="stylesheet" type="text/css">
  <link href="https://w3c.github.io/openscreenprotocol/" rel="canonical">
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-dfn-panel */

.dfn-panel {
    position: absolute;
    z-index: 35;
    height: auto;
    width: -webkit-fit-content;
    width: fit-content;
    max-width: 300px;
    max-height: 500px;
    overflow: auto;
    padding: 0.5em 0.75em;
    font: small Helvetica Neue, sans-serif, Droid Sans Fallback;
    background: #DDDDDD;
    color: black;
    border: outset 0.2em;
}
.dfn-panel:not(.on) { display: none; }
.dfn-panel * { margin: 0; padding: 0; text-indent: 0; }
.dfn-panel > b { display: block; }
.dfn-panel a { color: black; }
.dfn-panel a:not(:hover) { text-decoration: none !important; border-bottom: none !important; }
.dfn-panel > b + b { margin-top: 0.25em; }
.dfn-panel ul { padding: 0; }
.dfn-panel li { list-style: inside; }
.dfn-panel.activated {
    display: inline-block;
    position: fixed;
    left: .5em;
    bottom: 2em;
    margin: 0 auto;
    max-width: calc(100vw - 1.5em - .4em - .5em);
    max-height: 30vh;
}

.dfn-paneled { cursor: pointer; }
</style>
<style>/* style-selflinks */

.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: gray;
    color: white;
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: black;
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: #005a9c;
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}</style>
 <body class="h-entry">
  <div class="head">
   <p data-fill-with="logo"><a class="logo" href="https://www.w3.org/"> <img alt="W3C" height="48" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" width="72"> </a> </p>
   <h1 class="p-name no-ref" id="title">Open Screen Protocol</h1>
   <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Editor’s Draft, <time class="dt-updated" datetime="1970-01-01">1 January 1970</time></span></h2>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://w3c.github.io/openscreenprotocol/">https://w3c.github.io/openscreenprotocol/</a>
     <dt class="editor">Editor:
     <dd class="editor p-author h-card vcard" data-editor-id="68454"><a class="p-name fn u-url url" href="https://github.com/mfoltzgoogle">Mark Foltz</a> (<span class="p-org org">Google</span>)
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <p class="copyright" data-fill-with="copyright"><a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 1970 <a href="https://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href="https://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a href="https://www.ercim.eu/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a href="https://www.keio.ac.jp/">Keio</a>, <a href="https://ev.buaa.edu.cn/">Beihang</a>). W3C <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document" rel="license">permissive document license</a> rules apply. </p>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>The Open Screen Protocol is a suite of network protocols that allow

          user agents to implement the <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a> and
          the <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> in an interoperable
          fashion.</p>
  </div>
  <h2 class="no-num no-toc no-ref heading settled" id="status"><span class="content">Status of this document</span></h2>
  <div data-fill-with="status">
   <p> <em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and the latest revision of this technical report can be found in the <a href="https://www.w3.org/TR/"><abbr title="World Wide Web Consortium">W3C</abbr> technical reports index</a> at https://www.w3.org/TR/.</em> </p>
   <p> This document was published by the <a href="https://www.w3.org/2014/secondscreen/">Second Screen Working Group</a> as an Editor’s Draft. This document is intended to become a W3C Recommendation. </p>
   <p> Feedback and comments on this specification are welcome. Please use <a href="https://github.com/w3c/openscreenprotocol/issues">Github issues</a>. </p>
   <p> Publication as an Editor’s Draft does not imply endorsement by the <abbr title="World Wide Web Consortium">W3C</abbr> Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress. </p>
   <p> This document was produced by a group operating under the <a class="css" data-link-type="property" href="https://www.w3.org/Consortium/Patent-Policy/" id="sotd_patent">W3C Patent Policy</a>. <abbr title="World Wide Web Consortium">W3C</abbr> maintains a <a href="https://www.w3.org/2004/01/pp-impl/74168/status" rel="disclosure">public list of any patent disclosures</a> made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains <a href="https://www.w3.org/Consortium/Patent-Policy/#def-essential">Essential
    Claim(s)</a> must disclose the information in accordance with <a href="https://www.w3.org/Consortium/Patent-Policy/#sec-Disclosure">section 6 of the <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>. </p>
   <p> This document is governed by the <a href="https://www.w3.org/2019/Process-20190301/" id="w3c_process_revision">1 March 2019 W3C Process Document</a>. </p>
   <p></p>
  </div>
  <div data-fill-with="at-risk"></div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li>
     <a href="#introduction"><span class="secno">1</span> <span class="content">Introduction</span></a>
     <ol class="toc">
      <li><a href="#terminology"><span class="secno">1.1</span> <span class="content">Terminology</span></a>
     </ol>
    <li>
     <a href="#requirements"><span class="secno">2</span> <span class="content">Requirements</span></a>
     <ol class="toc">
      <li><a href="#requirements-general"><span class="secno">2.1</span> <span class="content">General Requirements</span></a>
      <li><a href="#requirements-presentation-api"><span class="secno">2.2</span> <span class="content">Presentation API Requirements</span></a>
      <li><a href="#requirements-remote-playback"><span class="secno">2.3</span> <span class="content">Remote Playback API Requirements</span></a>
      <li><a href="#requirements-non-functional"><span class="secno">2.4</span> <span class="content">Non-Functional Requirements</span></a>
     </ol>
    <li><a href="#discovery"><span class="secno">3</span> <span class="content">Discovery with mDNS</span></a>
    <li>
     <a href="#transport"><span class="secno">4</span> <span class="content">Transport and metadata discovery with QUIC</span></a>
     <ol class="toc">
      <li><a href="#tls-13"><span class="secno">4.1</span> <span class="content">TLS 1.3</span></a>
      <li><a href="#certificates"><span class="secno">4.2</span> <span class="content">Agent Certificates</span></a>
      <li><a href="#metadata"><span class="secno">4.3</span> <span class="content">Metadata Discovery</span></a>
     </ol>
    <li>
     <a href="#messages"><span class="secno">5</span> <span class="content">Messages delivery using CBOR and QUIC streams</span></a>
     <ol class="toc">
      <li><a href="#message-compatibility"><span class="secno">5.1</span> <span class="content">Type Key Backwards Compatibility</span></a>
     </ol>
    <li>
     <a href="#authentication"><span class="secno">6</span> <span class="content">Authentication</span></a>
     <ol class="toc">
      <li><a href="#authentication-with-spake2"><span class="secno">6.1</span> <span class="content">Authentication with SPAKE2</span></a>
     </ol>
    <li>
     <a href="#presentation-protocol"><span class="secno">7</span> <span class="content">Presentation Protocol</span></a>
     <ol class="toc">
      <li><a href="#presentation-api"><span class="secno">7.1</span> <span class="content">Presentation API</span></a>
     </ol>
    <li>
     <a href="#remote-playback-protocol"><span class="secno">8</span> <span class="content">Remote Playback Protocol</span></a>
     <ol class="toc">
      <li><a href="#remote-playback-state-and-controls"><span class="secno">8.1</span> <span class="content">Remote Playback State and Controls</span></a>
      <li><a href="#remote-playback-api"><span class="secno">8.2</span> <span class="content">Remote Playback API</span></a>
     </ol>
    <li>
     <a href="#streaming-protocol"><span class="secno">9</span> <span class="content">Streaming Protocol</span></a>
     <ol class="toc">
      <li><a href="#streaming-protocol-capabilities"><span class="secno">9.1</span> <span class="content">Streaming Protocol Capabilities</span></a>
      <li><a href="#streaming-sessions"><span class="secno">9.2</span> <span class="content">Sessions</span></a>
      <li><a href="#streaming-audio"><span class="secno">9.3</span> <span class="content">Audio</span></a>
      <li><a href="#streaming-video"><span class="secno">9.4</span> <span class="content">Video</span></a>
      <li><a href="#streaming-data"><span class="secno">9.5</span> <span class="content">Data</span></a>
      <li><a href="#streaming-feedback"><span class="secno">9.6</span> <span class="content">Feedback</span></a>
      <li><a href="#streaming-stats"><span class="secno">9.7</span> <span class="content">Stats</span></a>
     </ol>
    <li><a href="#requests-responses-watches"><span class="secno">10</span> <span class="content">Requests, Responses, and Watches</span></a>
    <li>
     <a href="#protocol-extensions"><span class="secno">11</span> <span class="content">Protocol Extensions</span></a>
     <ol class="toc">
      <li><a href="#protocol-extension-fields"><span class="secno">11.1</span> <span class="content">Protocol Extension Fields</span></a>
     </ol>
    <li>
     <a href="#security-privacy"><span class="secno">12</span> <span class="content">Security and Privacy</span></a>
     <ol class="toc">
      <li>
       <a href="#threat-models"><span class="secno">12.1</span> <span class="content">Threat Models</span></a>
       <ol class="toc">
        <li><a href="#passive-network-attackers"><span class="secno">12.1.1</span> <span class="content">Passive Network Attackers</span></a>
        <li><a href="#active-network-attackers"><span class="secno">12.1.2</span> <span class="content">Active Network Attackers</span></a>
        <li><a href="#denial-of-service"><span class="secno">12.1.3</span> <span class="content">Denial of Service</span></a>
        <li><a href="#same-origin-policy-violations"><span class="secno">12.1.4</span> <span class="content">Same-Origin Policy Violations</span></a>
       </ol>
      <li>
       <a href="#security-privacy-questions"><span class="secno">12.2</span> <span class="content">Open Screen Protocol Security and Privacy Considerations</span></a>
       <ol class="toc">
        <li><a href="#personally-identifiable-information"><span class="secno">12.2.1</span> <span class="content">Personally Identifiable Information &amp; High-Value Data</span></a>
        <li><a href="#cross-origin-state"><span class="secno">12.2.2</span> <span class="content">Cross Origin State Considerations</span></a>
        <li><a href="#origin-access-devices"><span class="secno">12.2.3</span> <span class="content">Origin Access to Other Devices</span></a>
        <li><a href="#incognito-mode"><span class="secno">12.2.4</span> <span class="content">Incognito Mode</span></a>
        <li><a href="#persistent-state"><span class="secno">12.2.5</span> <span class="content">Persistent State</span></a>
        <li><a href="#other-considerations"><span class="secno">12.2.6</span> <span class="content">Other Considerations</span></a>
       </ol>
      <li><a href="#presentation-api-considerations"><span class="secno">12.3</span> <span class="content">Presentation API Considerations</span></a>
      <li><a href="#remote-playback-considerations"><span class="secno">12.4</span> <span class="content">Remote Playback API Considerations</span></a>
      <li>
       <a href="#security-mitigations"><span class="secno">12.5</span> <span class="content">Mitigation Strategies</span></a>
       <ol class="toc">
        <li><a href="#local-passive-mitigations"><span class="secno">12.5.1</span> <span class="content">Local passive network attackers</span></a>
        <li><a href="#local-active-mitigations"><span class="secno">12.5.2</span> <span class="content">Local active network attackers</span></a>
        <li><a href="#remote-active-mitigations"><span class="secno">12.5.3</span> <span class="content">Remote active network attackers</span></a>
        <li><a href="#denial-of-service-mitigations"><span class="secno">12.5.4</span> <span class="content">Denial of service</span></a>
        <li><a href="#malicious-input-mitigations"><span class="secno">12.5.5</span> <span class="content">Malicious input</span></a>
       </ol>
      <li>
       <a href="#security-ui"><span class="secno">12.6</span> <span class="content">User Interface Considerations</span></a>
       <ol class="toc">
        <li><a href="#instance-names"><span class="secno">12.6.1</span> <span class="content">Instance and Display Names</span></a>
       </ol>
     </ol>
    <li><a href="#appendix-a"><span class="secno"></span> <span class="content">Appendix A: Messages</span></a>
    <li><a href="#appendix-b"><span class="secno"></span> <span class="content">Appendix B: Message Type Key Ranges</span></a>
    <li>
     <a href="#index"><span class="secno"></span> <span class="content">Index</span></a>
     <ol class="toc">
      <li><a href="#index-defined-here"><span class="secno"></span> <span class="content">Terms defined by this specification</span></a>
      <li><a href="#index-defined-elsewhere"><span class="secno"></span> <span class="content">Terms defined by reference</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#normative"><span class="secno"></span> <span class="content">Normative References</span></a>
      <li><a href="#informative"><span class="secno"></span> <span class="content">Informative References</span></a>
     </ol>
    <li><a href="#issues-index"><span class="secno"></span> <span class="content">Issues Index</span></a>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="introduction"><span class="secno">1. </span><span class="content">Introduction</span><a class="self-link" href="#introduction"></a></h2>
   <p>The Open Screen Protocol connects browsers to devices capable of rendering Web
content for a shared audience.  Typically, these are devices like
Internet-connected TVs, HDMI dongles, and smart speakers.</p>
   <p>This spec defines a suite of network protocols that enable two user agents to
implement the <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a> and <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> in an interoperable fashion.  This means
that a Web developer can expect these APIs to work as intended when connecting
two devices from independent implementations of the Open Screen Protocol.</p>
   <p>The Open Screen Protocol is a specific implementation of these two APIs, meaning
that it does not handle all possible ways that browsers and presentation
displays could support these APIs.  The Open Screen Protocol specifically
supports browsers and displays that are connected via the same local area
network.  It allows a browser to present a URL, initiate remote playback of an
HTML <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/media.html#media-element" id="ref-for-media-element">media element</a>, and stream media data to another
device.</p>
   <p>The Open Screen Protocol is intended to be extensible, so that additional
capabilities can be added over time.  This may include additions to existing Web
APIs or new Web APIs.</p>
   <h3 class="heading settled" data-level="1.1" id="terminology"><span class="secno">1.1. </span><span class="content">Terminology</span><a class="self-link" href="#terminology"></a></h3>
   <p>An <dfn class="dfn-paneled" data-dfn-type="dfn" data-lt="open screen protocol agent|osp agent" data-noexport id="open-screen-protocol-agent">Open Screen Protocol
agent</dfn> (or OSP agent) is any implementation of this protocol (browser,
display, speaker, or other software).</p>
   <p>Some OSP agents support the <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a>.  The
API allows a <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-controlling-user-agent" id="ref-for-dfn-controlling-user-agent">controlling user agent</a> to initiate presentation of Web content
on another device.  We call this agent a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="controller">controller</dfn> for short.  A <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-receiving-user-agent" id="ref-for-dfn-receiving-user-agent">receiving user agent</a> is responsible for rendering the Web content, which we
will call a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="receiver">receiver</dfn> for short.  The the Web content itself is called
a <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation" id="ref-for-dfn-presentation">presentation</a>.</p>
   <p>Some OSP agents also support the <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a>.  That
API allows an agent to render a <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/media.html#media-element" id="ref-for-media-element①">media element</a> on a <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-remote-playback-devices" id="ref-for-dfn-remote-playback-devices">remote playback device</a>.  In this document, we refer to it as a <a data-link-type="dfn" href="#receiver" id="ref-for-receiver">receiver</a> because it is shorter and keeps terminology consistent between presentations and
remote playbacks. Similarly, we use the term <a data-link-type="dfn" href="#controller" id="ref-for-controller">controller</a> to refer to the
agent that starts, terminates, and controls the remote playback.</p>
   <p>For media streaming, we refer to an OSP agent that sends a media stream
as a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="media-sender">media sender</dfn> and an agent that receives a media stream as a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="media-receiver">media receiver</dfn>.  Note that an agent can be both a media sender and a
media receiver.</p>
   <p>For additional terms and idioms specific to the <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a> or <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a>,
please consult the respective specifications.</p>
   <h2 class="heading settled" data-level="2" id="requirements"><span class="secno">2. </span><span class="content">Requirements</span><a class="self-link" href="#requirements"></a></h2>
   <h3 class="heading settled" data-level="2.1" id="requirements-general"><span class="secno">2.1. </span><span class="content">General Requirements</span><a class="self-link" href="#requirements-general"></a></h3>
   <ol>
    <li data-md>
     <p>An <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent">Open Screen Protocol agent</a> must be able to discover the presence of
another OSP agent connected to the same IPv4 or IPv6 subnet and reachable by
IP multicast.</p>
    <li data-md>
     <p>An OSP agent must be able to obtain the IPv4 or IPv6 address of
the agent, a display name for the agent, and an IP port number for
establishing a network transport to the agent.</p>
   </ol>
   <h3 class="heading settled" data-level="2.2" id="requirements-presentation-api"><span class="secno">2.2. </span><span class="content">Presentation API Requirements</span><a class="self-link" href="#requirements-presentation-api"></a></h3>
   <ol>
    <li data-md>
     <p>A <a data-link-type="dfn" href="#controller" id="ref-for-controller①">controller</a> must be able to determine if a <a data-link-type="dfn" href="#receiver" id="ref-for-receiver①">receiver</a> is reasonably
capable of rendering a specific <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-request-url" id="ref-for-dfn-presentation-request-url">presentation request URL</a>.</p>
    <li data-md>
     <p>A controller must be able to start a new <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation" id="ref-for-dfn-presentation①">presentation</a> on a
receiver given a <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-request-url" id="ref-for-dfn-presentation-request-url①">presentation request URL</a> and <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-id" id="ref-for-dfn-presentation-id">presentation ID</a>.</p>
    <li data-md>
     <p>A controller must be able to create a new <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/presentation-api/#presentationconnection" id="ref-for-presentationconnection">PresentationConnection</a></code> to an
existing presentation on the receiver, given its <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-request-url" id="ref-for-dfn-presentation-request-url②">presentation request
URL</a> and <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-id" id="ref-for-dfn-presentation-id①">presentation ID</a>.</p>
    <li data-md>
     <p>It must be possible to close a <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/presentation-api/#presentationconnection" id="ref-for-presentationconnection①">PresentationConnection</a></code> between a
controller and a presentation, and signal both parties with the reason why
the connection was closed.</p>
    <li data-md>
     <p>Multiple controllers must be able to connect to a single presentation
simultaneously.</p>
    <li data-md>
     <p>Messages sent by the controller must be delivered to the presentation (or
vice versa) in a reliable and in-order fashion.</p>
    <li data-md>
     <p>If a message cannot be delivered, then the controller must be
able to signal the receiver (or vice versa) that the connection should be
closed with reason <code>error</code>.</p>
    <li data-md>
     <p>The controller and presentation must be able to send and receive <code>DOMString</code> messages (represented as <code>string</code> type in ECMAScript).</p>
    <li data-md>
     <p>The controller and presentation must be able to send and receive binary
messages (represented as <code>Blob</code> objects in HTML5, or <code>ArrayBuffer</code> or <code>ArrayBufferView</code> types in ECMAScript).</p>
    <li data-md>
     <p>The controller must be able to signal to the receiver to
terminate a presentation, given its <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-request-url" id="ref-for-dfn-presentation-request-url③">presentation request URL</a> and <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-id" id="ref-for-dfn-presentation-id②">presentation
ID</a>.</p>
    <li data-md>
     <p>The receiver must be able to signal all connected controllers
when a presentation is terminated.</p>
   </ol>
   <h3 class="heading settled" data-level="2.3" id="requirements-remote-playback"><span class="secno">2.3. </span><span class="content">Remote Playback API Requirements</span><a class="self-link" href="#requirements-remote-playback"></a></h3>
   <ol>
    <li data-md>
     <p>A <a data-link-type="dfn" href="#controller" id="ref-for-controller②">controller</a> must be able to find out whether there is at least one
compatible <a data-link-type="dfn" href="#receiver" id="ref-for-receiver②">receiver</a> for a given <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement" id="ref-for-htmlmediaelement">HTMLMediaElement</a></code>, both
instantaneously and continuously.</p>
    <li data-md>
     <p>A controller must be able to to <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-initiate-remote-playback" id="ref-for-dfn-initiate-remote-playback">initiate remote playback</a> of
an <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement" id="ref-for-htmlmediaelement①">HTMLMediaElement</a></code> to a compatible receiver.</p>
    <li data-md>
     <p>The controller must be able send media sources as URLs and text
tracks from an <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement" id="ref-for-htmlmediaelement②">HTMLMediaElement</a></code> to a compatible receiver.</p>
    <li data-md>
     <p>The controller must be able send media data from an <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement" id="ref-for-htmlmediaelement③">HTMLMediaElement</a></code> to
a compatible receiver.</p>
    <li data-md>
     <p>During remote playback, the controller and the remote playback
device must be able to synchronize the <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-element-state" id="ref-for-dfn-media-element-state">media element state</a> of the <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement" id="ref-for-htmlmediaelement④">HTMLMediaElement</a></code>.</p>
    <li data-md>
     <p>During remote playback, either the controller or the receiver must be able
to disconnect from the other party.</p>
    <li data-md>
     <p>The controller should be able to pass locale and text direction information
to the receiver to assist in rendering text during remote playback.</p>
   </ol>
   <h3 class="heading settled" data-level="2.4" id="requirements-non-functional"><span class="secno">2.4. </span><span class="content">Non-Functional Requirements</span><a class="self-link" href="#requirements-non-functional"></a></h3>
   <ol>
    <li data-md>
     <p>It should be possible to implement an OSP agent using modest
hardware requirements, similar to what is found in a low end smartphone,
smart TV or streaming device. See the <a href="device_specs.md">Device
Specifications</a> document for agent hardware specifications.</p>
    <li data-md>
     <p>The discovery and connection protocols should minimize power consumption,
especially on a <a data-link-type="dfn" href="#listening-agent" id="ref-for-listening-agent">listening agent</a> which is likely to be battery
powered.</p>
    <li data-md>
     <p>The protocol should minimize the amount of information provided to a passive
network observer about the identity of the user or activities on the agent, including
presentations, remote playbacks, or the content of media streams.</p>
    <li data-md>
     <p>The protocol should prevent active network attackers from impersonating a
display and observing or altering data intended for the controller or
receiver.</p>
    <li data-md>
     <p>A listening agent should be able to discover quickly when an <a data-link-type="dfn" href="#advertising-agent" id="ref-for-advertising-agent">advertising
agent</a> becomes available or unavailable (i.e., when it connects or
disconnects from the network).</p>
    <li data-md>
     <p>Agents should present sensible information to the user when a protocol
operation fails.  For example, if a controller is unable to start a
presentation, it should be possible to report in the controller interface if
it was a network error, authentication error, or the presentation content
failed to load.</p>
    <li data-md>
     <p>Agents should be able to remember that a user authenticated another agent.
This means it is not required for the user to intervene and re-authenticate
each time an agent wants to connect to an agent that the user has already
authenticated.</p>
    <li data-md>
     <p>Message latency between agents should be minimized to permit interactive
use.  For example, it should be comfortable to type in a form in one agent
and have the text appear in the presentation in real time.  Real-time
latency for gaming or mouse use is ideal, but not a requirement.</p>
    <li data-md>
     <p>The controller initiating a presentation or remote playback should
communicate its preferred locale to the receiver, so it can render the
content in that locale.</p>
    <li data-md>
     <p>It should be possible to extend the control protocol (above the discovery and
transport levels) with optional features not defined explicitly by the
specification, to facilitate experimentation and enhancement of the base
APIs.</p>
   </ol>
   <h2 class="heading settled" data-level="3" id="discovery"><span class="secno">3. </span><span class="content">Discovery with mDNS</span><a class="self-link" href="#discovery"></a></h2>
   <p><a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent①">Open Screen Protocol agents</a> must discover one another using <a data-link-type="biblio" href="#biblio-rfc6763">DNS-SD</a> over <a data-link-type="biblio" href="#biblio-rfc6762">mDNS</a>.  To do so, OSP agents must use the <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc6763#section-7" id="ref-for-section-7">Service Name</a> <code>_openscreen._udp.local</code>.</p>
   <p class="issue" id="issue-56c2cd35"><a class="self-link" href="#issue-56c2cd35"></a> Define suspend and resume behavior for discovery protocol. <a href="https://github.com/w3c/openscreenprotocol/issues/107">&lt;https://github.com/w3c/openscreenprotocol/issues/107></a></p>
   <p>An <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="advertising-agent">advertising agent</dfn> is one that responds to mDNS queries
for <code>_openscreen._udp.local</code>.  Such an agent should have a <dfn class="dfn-paneled" data-dfn-type="dfn" data-lt="display name" data-noexport id="display-name">display
name</dfn> (a non-empty string) that is a human readable description of the
presentation display, e.g. "Living Room TV."</p>
   <p>A <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="listening-agent">listening agent</dfn> is one that sends mDNS queries for <code>_openscreen._udp.local</code>.  Listening agents may have a display name.</p>
   <p>Advertising agents must use a DNS-SD <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc6763#section-4.1.1" id="ref-for-section-4.1.1">Instance Name</a> that is a prefix of the
agent’s display name.  If the Instance Name is not the complete display name, it
must be terminated by a null (<code>\000</code>) character, so that a listening agent knows
it has been truncated.</p>
   <p>Advertising agents must follow the mDNS <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc6762#section-9" id="ref-for-section-9">conflict resolution</a> procedure, to
prevent multiple advertising agents from using the same DNS-SD Instance Name.</p>
   <p>Agents should be careful when displaying Instance Names to users; see <a href="#instance-names">§ 12.6.1 Instance and Display Names</a> for guidelines on Instance Name display.</p>
   <p>Advertising agents must include DNS TXT records with the following
keys and values:</p>
   <dl>
    <dt data-md>fp
    <dd data-md>
     <p>The <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="agent-fingerprint">agent fingerprint</dfn> of the advertising agent, computed over the <a data-link-type="dfn" href="#agent-certificate" id="ref-for-agent-certificate">agent certificate</a>. The format of the fingerprint is defined by <a data-link-type="biblio" href="#biblio-rfc5122">[RFC5122]</a>,
excluding the "fingerprint:" prefix and including the hash function, space,
and hex-encoded fingerprint.  The fingerprint value also functions as an ID
for the agent. All agents must support the following hash functions: <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8122#section-5" id="ref-for-section-5">sha-256</a>, <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8122#section-5" id="ref-for-section-5①">sha-512</a>.  Agents must not support the following hash functions: <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8122#section-5" id="ref-for-section-5②">md2</a>, <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc8122#section-5" id="ref-for-section-5③">md5</a>.</p>
    <dt data-md>mv
    <dd data-md>
     <p>An unsigned integer value that indicates that
metadata has changed.   The advertising agent must update it to a greater
value.  This signals to the listening agent that it should connect to the
advertising agent to discover updated metadata.</p>
    <dt data-md>at
    <dd data-md>
     <p>An alphanumeric, unguessable token consisting of characters from the set <code>[A-Za-z0-9+/]</code>.</p>
   </dl>
   <p class="note" role="note"><span>Note:</span> <code>at</code> prevents off-LAN parties from attempting authentication; see <a href="#remote-active-mitigations">§ 12.5.3 Remote active network attackers</a>. <code>at</code> should have at least 32 bits of true
entropy to make brute force attacks impractical.</p>
   <p class="issue" id="issue-49bdd4e6"><a class="self-link" href="#issue-49bdd4e6"></a> Add examples of sample mDNS records.</p>
   <p>Future extensions to this QUIC-based protocol can use the same metadata
discovery process to indicate support for those extensions, through a
capabilities mechanism to be determined. If a future version of the Open Screen
Protocol uses mDNS but breaks compatibility with the metadata discovery process,
it should change the DNS-SD service name to a new value, indicating a new
mechanism for metadata discovery.</p>
   <h2 class="heading settled" data-level="4" id="transport"><span class="secno">4. </span><span class="content">Transport and metadata discovery with QUIC</span><a class="self-link" href="#transport"></a></h2>
   <p>If a <a data-link-type="dfn" href="#listening-agent" id="ref-for-listening-agent①">listening agent</a> wants to connect to or learn further metadata about an <a data-link-type="dfn" href="#advertising-agent" id="ref-for-advertising-agent①">advertising agent</a>, it initiates a <span>[QUIC]</span> connection to the IP and port
from its SRV record.  Prior to authentication, a message may be exchanged (such
as further metadata), but such info should be treated as unverified (such as
indicating to a user that a display name of an unauthenticated agent is
unverified).</p>
   <p>The connection IDs used both by agents should be zero length.  If zero length
connection IDs are chosen, agents are restricted from changing IP or port
without establishing a new QUIC connection.  In such cases, agents must
establish a new QUIC connection in order to change IP or port.</p>
   <h3 class="heading settled" data-level="4.1" id="tls-13"><span class="secno">4.1. </span><span class="content">TLS 1.3</span><a class="self-link" href="#tls-13"></a></h3>
   <p>When an <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent②">OSP Agent</a> makes a QUIC connection to another agent, it must use <a data-link-type="biblio" href="#biblio-rfc8446">TLS 1.3</a> to secure the connection.  TLS 1.3 must be used in the following
application profile:</p>
   <ul>
    <li data-md>
     <p>The <a data-link-type="biblio" href="#biblio-rfc7301">ALPN</a> used must be "osp".</p>
    <li data-md>
     <p>Only constant-time AEAD ciphers are allowed.</p>
     <ul>
      <li data-md>
       <p>OSP agents must support <a data-link-type="biblio" href="#biblio-rfc8446">TLS_AES_128_GCM_SHA256</a>.</p>
      <li data-md>
       <p>OSP agents should support <a data-link-type="biblio" href="#biblio-rfc8466">TLS_CHACHA20_POLY1305_SHA256</a> and <a data-link-type="biblio" href="#biblio-rfc8466">TLS_AES_256_GCM_SHA384</a>.</p>
     </ul>
    <li data-md>
     <p>OSP agents must support the <a data-link-type="biblio" href="#biblio-rfc8446">ecdsa_secp256r1_sha256</a> digital signature algorithm.
OSP agents should also support <a data-link-type="biblio" href="#biblio-rfc8466">ecdsa_secp384r1_sha384</a> and <a data-link-type="biblio" href="#biblio-rfc8466">ecdsa_secp521r1_sha512</a>. OSP agents must not support additional digital
signature algorithms.</p>
     <ul>
      <li data-md>
       <p><code>ecdsa_secp256r1_sha256</code> must be included in the <code>signature_algorithms</code> extension. <code>ecdsa_secp384r1_sha384</code> and <code>ecdsa_secp512r1_sha512</code> must be
included if they are supported by the agent.</p>
      <li data-md>
       <p><code>secp256r1</code> must be included in the <code>supported_groups</code> extension. <code>secp384r1</code> and <code>secp512r1</code> must be included if they are supported by the
agent.</p>
      <li data-md>
       <p>The <code>key_share</code> extension must be set to the cryptographic parameters for
the negotiated signature algoirithm.</p>
     </ul>
    <li data-md>
     <p>The <code>server_name</code> extension should be set to the following <code>host_name</code>: <code>&lt;fp>._openscreen._udp.local</code>.</p>
     <ul>
      <li data-md>
       <p><code>&lt;fp></code> should be substituted with the <a data-link-type="dfn" href="#agent-fingerprint" id="ref-for-agent-fingerprint">agent fingerprint</a> as used in mDNS TXT.</p>
     </ul>
    <li data-md>
     <p>All other TLS 1.3 extensions must be ignored by OSP agents.</p>
   </ul>
   <p class="note" role="note"><span>Note:</span> As this is an application-specific profile for TLS 1.3, it is not required
for OSP agents to interoperate with non-OSP TLS 1.3 endpoints.</p>
   <p class="issue" id="issue-808efb48"><a class="self-link" href="#issue-808efb48"></a> Register ALPN with IANA. <a href="https://github.com/w3c/openscreenprotocol/issues/228">&lt;https://github.com/w3c/openscreenprotocol/issues/228></a></p>
   <p class="issue" id="issue-eb53583c"><a class="self-link" href="#issue-eb53583c"></a> Determine if there is an advantage to session resumption outside of
early data. If we allow session resumption, do we allow early data too? <a href="https://github.com/w3c/openscreenprotocol/issues/220">&lt;https://github.com/w3c/openscreenprotocol/issues/220></a></p>
   <p class="issue" id="issue-983764c9"><a class="self-link" href="#issue-983764c9"></a> Do agents need to support the Cookies extension (used in
HelloRetryRequest)? <a href="https://github.com/w3c/openscreenprotocol/issues/219">&lt;https://github.com/w3c/openscreenprotocol/issues/219></a></p>
   <p class="issue" id="issue-08dfa2ca"><a class="self-link" href="#issue-08dfa2ca"></a> Make recommendations for cipher and signature algorithm preference
list based on hardware characteristics of agents. <a href="https://github.com/w3c/openscreenprotocol/issues/218">&lt;https://github.com/w3c/openscreenprotocol/issues/218></a></p>
   <h3 class="heading settled" data-level="4.2" id="certificates"><span class="secno">4.2. </span><span class="content">Agent Certificates</span><a class="self-link" href="#certificates"></a></h3>
   <p>Each OSP Agent must generate an <a data-link-type="biblio" href="#biblio-rfc5280">X.509 v3</a> <dfn class="dfn-paneled" data-dfn-type="dfn" data-lt="agent certificate" data-noexport id="agent-certificate">agent
certificate</dfn> containing a public key to be used with the TLS 1.3
certificate exchange.  Both <a data-link-type="dfn" href="#advertising-agent" id="ref-for-advertising-agent②">advertising agents</a> and <a data-link-type="dfn" href="#listening-agent" id="ref-for-listening-agent②">listening agents</a> must
use the <a data-link-type="dfn" href="#agent-certificate" id="ref-for-agent-certificate①">agent certificate</a> in TLS 1.3 <code>Certificate</code> messages when making a
QUIC connection.</p>
   <p>The <a data-link-type="dfn" href="#agent-certificate" id="ref-for-agent-certificate②">agent certificate</a> must have the following characteristics:</p>
   <ul>
    <li data-md>
     <p>256-bit, 384-bit, or 521-bit ECDSA public key</p>
    <li data-md>
     <p>Self-signed</p>
    <li data-md>
     <p>Supporting the at least one of the following signature algorithms:</p>
     <ul>
      <li data-md>
       <p>secp256r1_sha256</p>
      <li data-md>
       <p>secp384r1_sha384</p>
      <li data-md>
       <p>secp521r1_sha512</p>
     </ul>
    <li data-md>
     <p>Valid for signing</p>
   </ul>
   <p>The following X.509 v3 fields are to be set as follows:</p>
   <table>
    <thead>
     <tr>
      <th>Field
      <th>Value
    <tbody>
     <tr>
      <td>Version Number
      <td>3
     <tr>
      <td>Serial Number
      <td><code>&lt;fp></code>
     <tr>
      <td>Signature Algorithm ID
      <td>One of the values listed above.
     <tr>
      <td>Issuer Name
      <td>CN = The <code>model-name</code> from the <code>agent-info</code> message.<br> O = See note.<br> L = See note.<br> ST = See note.<br> C = See note.<br> 
     <tr>
      <td>Subject Name
      <td>CN = <code>&lt;fp></code>._openscreen._udp.local<br> O = See note.<br> 
     <tr>
      <td>Subject Public Key Algorithm
      <td>Elliptic Curve Public Key
     <tr>
      <td>Certificate Key usage
      <td>Signing
   </table>
   <p>Mandatory fields not mentioned above should be set according to <a data-link-type="biblio" href="#biblio-rfc5280">[RFC5280]</a>.</p>
   <p>The value <code>&lt;fp></code> above should be substituted with the <a data-link-type="dfn" href="#agent-fingerprint" id="ref-for-agent-fingerprint①">agent fingerprint</a> (as
serialized in mDNS TXT).</p>
   <p class="note" role="note"><span>Note:</span> The OSP agent may use the implementer or device model name as the value
for the <code>O</code> key for user interface and debugging purposes. It may use the agent
implementer’s or device manufacturer’s location as the value for the location
keys (<code>L</code>, <code>ST</code>, and <code>C</code>) for user interface and debugging purposes.</p>
   <p>If an OSP agent sees an <a data-link-type="dfn" href="#agent-certificate" id="ref-for-agent-certificate③">agent certificate</a> it has not yet verified through <a href="#authentication">§ 6 Authentication</a>, it must treat that agent as unverified and initiate
authentication with that agent before allowing additional messages to be
exchanged with that agent (apart from the messages described in <a href="#metadata">§ 4.3 Metadata Discovery</a>).</p>
   <p>If an OSP agent sees a valid <a data-link-type="dfn" href="#agent-certificate" id="ref-for-agent-certificate④">agent certificate</a> it has verified through
authentication, it is not required to initiate authentication with that agent
before sending further messages.</p>
   <h3 class="heading settled" data-level="4.3" id="metadata"><span class="secno">4.3. </span><span class="content">Metadata Discovery</span><a class="self-link" href="#metadata"></a></h3>
   <p>To learn further metadata, an agent may send an <a data-link-type="dfn">agent-info-request</a> message
and receive back an <a data-link-type="dfn">agent-info-response</a> message.  Any agent may send this
request at any time to learn about the state and capabilities of another device,
which are described by the <a data-link-type="dfn">agent-info</a> message in the <a data-link-type="dfn">agent-info-response</a>.</p>
   <p>If an agent changes any information in its <a data-link-type="dfn">agent-info</a> message, it should
send an <a data-link-type="dfn">agent-info-event</a> message to all other connected agents with the new <a data-link-type="dfn">agent-info</a> (without waiting for an <a data-link-type="dfn">agent-info-request</a>).</p>
   <p>The <a data-link-type="dfn">agent-info</a> message contains the following fields:</p>
   <dl>
    <dt data-md>display-name (required)
    <dd data-md>
     <p>The display name of the agent, intended to be displayed to a user by the
 requester. The requester should indicate through the UI if the responder
 is not authenticated or if the display name changes.</p>
    <dt data-md>model-name (optional)
    <dd data-md>
     <p>If the agent is a hardware device, the model name of
the device.  This is used mainly for debugging purposes, but may be
displayed to the user of the requesting agent.</p>
    <dt data-md>capabilities (required)
    <dd data-md>
     <p>The control protocols, roles, and media types the agent supports.
Presence indicates a capability and absence indicates lack of a
capability.  Capabilities should should affect how an agent is
presented to a user, such as drawing a different icon depending on
the media types it supports.</p>
    <dt data-md>state-token (required)
    <dd data-md>
     <p>A random alphanumeric value consisting of 8 characters in the range
[0-9A-Za-z].  This value is set before the agent makes its first connection
and must be set to a new value when the agent is reset or otherwise lost all
of its state related to this protocol.</p>
    <dt data-md>locales (required)
    <dd data-md>
     <p>The agent’s preferred locales for display of localized content, in the order
of user preference.  Each entry is an RFC5646 <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc5646#section-2" id="ref-for-section-2">language tag</a>.</p>
   </dl>
   <p>The various capabilities have the following meanings:</p>
   <dl>
    <dt data-md>receive-audio
    <dd data-md>
     <p>The agent can generally receive audio for the control protocols it
supports.  Each control protocol can have more specific capability
mechanisms, such as support for specific URLs in the presentation
protocol.</p>
    <dt data-md>receive-video
    <dd data-md>
     <p>The agent can generally receive video for the control protocols it
supports.  Each control protocol can have more specific capability
mechanisms, such as support for specific URLs in the presentation
protocol.</p>
    <dt data-md>receive-presentation
    <dd data-md>
     <p>The agent can receive presentations using the presentation protocol.</p>
    <dt data-md>control-presentation
    <dd data-md>
     <p>The agent can control presentations using the presentation protocol.</p>
    <dt data-md>receive-remote-playback
    <dd data-md>
     <p>The agent can receive remote playback using the remote playback
protocol.</p>
    <dt data-md>control-remote-playback
    <dd data-md>
     <p>The agent can control remote playback using the remote playback
protocol.</p>
    <dt data-md>receive-streaming
    <dd data-md>
     <p>The agent can receiving streaming using the streaming protocol.</p>
    <dt data-md>send-streaming
    <dd data-md>
     <p>The agent can send streaming using the streaming protocol.</p>
   </dl>
   <p class="note" role="note"><span>Note:</span> See the <a href="https://w3c.github.io/openscreenprotocol/capabilities.md">Capabilities Registry</a> for a list of all known capabilities (both defined by this specification, and
through <a href="#protocol-extensions">§ 11 Protocol Extensions</a>).</p>
   <p>If a listening agent wishes to receive messages from an advertising agent or an
advertising agent wishes to send messages to a listening agent, it may wish to
keep the QUIC connection alive.  Once neither side needs to keep the connection
alive for the purposes of sending or receiving messages, the connection should
be closed with an error code of 5139.  In order to keep a QUIC connection alive, an
agent may send an <a data-link-type="dfn">agent-status-request</a> message, and any agent that receives an <a data-link-type="dfn">agent-status-request</a> message should send an <a data-link-type="dfn">agent-status-response</a> message. Such
messages should be sent more frequently than the QUIC idle_timeout transport
parameter (see <a data-link-type="dfn" href="https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-18" id="ref-for-section-18">Transport Parameter Encoding</a> in <span>[QUIC]</span>) and QUIC PING
frames should not be used.  An idle_timeout transport parameter of 25 seconds is
recommended.  The agent should behave as though a timer less than the
idle_timeout were reset every time a message is sent on a QUIC stream.  If the
timer expires, a <a data-link-type="dfn">agent-status-request</a> message should be sent.</p>
   <p>If a listening agent wishes to send messages to an advertising agent, the
listening agent can connect to the advertising agent "on demand"; it does not
need to keep the connection alive.</p>
   <p class="issue" id="issue-e0955a17"><a class="self-link" href="#issue-e0955a17"></a> Define suspend and resume behavior for connection protocol. <a href="https://github.com/w3c/openscreenprotocol/issues/108">&lt;https://github.com/w3c/openscreenprotocol/issues/108></a></p>
   <p>The <a data-link-type="dfn">agent-info</a> and <a data-link-type="dfn">agent-status-response</a> messages may be extended to
include additional information not defined in this spec, as described in <a href="#protocol-extension-fields">§ 11.1 Protocol Extension Fields</a>.</p>
   <h2 class="heading settled" data-level="5" id="messages"><span class="secno">5. </span><span class="content">Messages delivery using CBOR and QUIC streams</span><a class="self-link" href="#messages"></a></h2>
   <p>Messages are serialized using <a data-link-type="biblio" href="#biblio-rfc7049">CBOR</a>.  To send a group of messages in
order, that group of messages must be sent in one QUIC stream.  Independent
groups of messages (with no ordering dependency across groups) should be sent in
different QUIC streams.  In order to put multiple CBOR-serialized messages into
the the same QUIC stream, the following is used.</p>
   <p>For each message, the <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent③">OSP agent</a> must write to the QUIC stream the following:</p>
   <ol>
    <li data-md>
     <p>A type key representing the type of the message, encoded as a variable-length
integer (see <a href="#appendix-a">Appendix A: Messages</a> for type keys)</p>
    <li data-md>
     <p>The message encoded as CBOR.</p>
   </ol>
   <p>If an agent receives a message for which it does not recognize a type key, it
must close the QUIC connection with an application error code of 404 and should
include the unknown type key in the reason phrase of the <a data-link-type="dfn" href="https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-19.19" id="ref-for-section-19.19">CONNECTION_CLOSE
frame</a>.</p>
   <p>Variable-length integers are encoded in the <a data-link-type="dfn" href="https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-16" id="ref-for-section-16">Variable-Length Integer Encoding</a> used by <span>[QUIC]</span>.</p>
   <p>Many messages are requests and responses, so a common format is defined for
those.  A request and a response includes a request ID which is an unsigned
integer chosen by the requester.  Responses must include the request ID of the
request they are associated with.</p>
   <h3 class="heading settled" data-level="5.1" id="message-compatibility"><span class="secno">5.1. </span><span class="content">Type Key Backwards Compatibility</span><a class="self-link" href="#message-compatibility"></a></h3>
   <p>As messages are modified or extended over time, certain rules must be followed
to maintain backwards compatibiilty with agents that understand older versions
of messages.</p>
   <ol>
    <li data-md>
     <p>If a required field is added to or removed from a message (either to/from the
message directly or indirectly through the field of a field), a new type key
must be assigned to the message.  Is is effectively a new message and must not
be sent unless the receiving agent is known to understand the new type key.</p>
    <li data-md>
     <p>If an optional field is added to a message (either to the message directly
or indirectly through the field of a field), the type key may remain unchanged
if the behavior of older receiving agents that do not understand the added field
is compatible with newer sending agents that include the field.
Otherwise, a new type key must be assigned.</p>
    <li data-md>
     <p>If an optional field is removed from a message (either from the message
directly or indirectly through the field of a field), the type key may remain
unchanged if the behavior of newer receiving agents that do not understand the
removed field is compatible with older sending agents that include the field.
Otherwise, a new type key must be assigned.</p>
    <li data-md>
     <p>Required fields may not be added or removed from array-based messages, such
as audio-frame.</p>
   </ol>
   <h2 class="heading settled" data-level="6" id="authentication"><span class="secno">6. </span><span class="content">Authentication</span><a class="self-link" href="#authentication"></a></h2>
   <p>Each supported authentication method is implemeted via authentication messages
specific to that method.  The authentication method is explicitly specified by
the message itself.  The authentication status message is common for all authentication
methods.  Any new authentication method added must define new authentication messages.</p>
   <p><a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent④">Open Screen Protocol agents</a> must implement <a href="#authentication-with-spake2">§ 6.1 Authentication with SPAKE2</a> with pre-shared keys.</p>
   <p>Prior to authentication, agents exchange <a data-link-type="dfn">auth-capabilities</a> messages specifying
pre-shared key (PSK) ease of input for the user and supported PSK input methods.
The agent with the lowest PSK ease of input presents a PSK to the user when the agent
either sends or receives an authentication request.  In case both agents have the same
PSK ease of input value, the server presents the PSK to the user.  The same pre-shared key
is used by both agents.  The agent presenting the PSK to the user is the PSK presenter,
the agent requiring the user to input the PSK is the PSK consumer.</p>
   <p>PSK ease of input is an integer in the range from 0 to 100 inclusive, where 0 means
it is not possible for the user to input PSK on this device and 100 means
that it’s easy for the user to input PSK on the device.  Supported PSK input methods
are numeric and scanning a QR-code.  Devices with non-zero PSK ease of input must
support the numeric PSK input method.</p>
   <p>Any authentication method may require an <a data-link-type="dfn">auth-initiation-token</a> before
showing a PSK to the user or requesting PSK input from the user.  For an <a data-link-type="dfn" href="#advertising-agent" id="ref-for-advertising-agent③">advertising agent</a>, the <code>at</code> field in its mDNS TXT record must be used as the <code>auth-initation-token</code> in the the first authentication message sent to or from
that agent.  Agents should discard any authentication message whose <code>auth-initation-token</code> is set and does not match the <code>at</code> provided by the
advertising agent.</p>
   <p>In the <code>psk-min-bits-of-entropy</code> field of the <a data-link-type="dfn">auth-capabilities</a> messsage,
agents may specify the minimum bits of entropy it requires for a PSK, in the
range of 20 to 60 bits inclusive, with a default of 20.  The PSK presenter must
generate a PSK that has at least as many bits of entropy as it receives in this
field, and at least as many bits of entropy as it sends in this field.</p>
   <p>If an agent chooses to show a user a PSK in more than one way (such as both a
QR-code and a numeric PSK), they should be for the same PSK.  If they were
different, the PSK presenter would not know which one the user chose to use, and
that may lead to authentication failures.</p>
   <h3 class="heading settled" data-level="6.1" id="authentication-with-spake2"><span class="secno">6.1. </span><span class="content">Authentication with SPAKE2</span><a class="self-link" href="#authentication-with-spake2"></a></h3>
   <p>For all messages and objects defined in this section, see Appendix A for
the full CDDL definitions.</p>
   <p>The default authentication method is <a href="https://tools.ietf.org/html/draft-irtf-cfrg-spake2-08">SPAKE2</a> with
the following cipher suite:</p>
   <ol>
    <li data-md>
     <p>Elliptic curve is <a href="https://tools.ietf.org/html/rfc7748#page-4">Curve25519</a>.</p>
    <li data-md>
     <p>Hash function is <a href="https://tools.ietf.org/html/rfc6234">SHA-512</a>.</p>
    <li data-md>
     <p>Key derivation function is <a href="https://tools.ietf.org/html/rfc5869">HKDF</a>.</p>
    <li data-md>
     <p>Message authentication code is <a href="https://tools.ietf.org/html/rfc2104">HMAC</a>.</p>
    <li data-md>
     <p>Password hash function is SHA-512.</p>
   </ol>
   <p>Open Screen Protocol does not use a memory-hard hash function to hash PSKs
with SPAKE2 and uses SHA-512 instead as the PSK is one-time use and
is not stored in any form.</p>
   <p>SPAKE2 provides explicit mutual authentication.</p>
   <p>This authentication method assumes the agents share a low-entropy secret,
such as a number or a short password that could be entered by a user on a
phone, a keyboard or a TV remote control.</p>
   <p>SPAKE2 is not symmetric and has two roles, Alice (A) and Bob (B).
The client acts as Alice, the server acts as Bob.</p>
   <p class="issue" id="issue-492f86ab"><a class="self-link" href="#issue-492f86ab"></a> What do "client" and "server" mean here?</p>
   <p>The messages used in this authentication method are: <a data-link-type="dfn">auth-spake2-need-psk</a>, <a data-link-type="dfn">auth-spake2-handshake</a>, <a data-link-type="dfn">auth-spake2-confirmation</a> and <a data-link-type="dfn">auth-status</a>.
SPAKE2 describes in detail how <a data-link-type="dfn">auth-spake2-handshake</a> and <a data-link-type="dfn">auth-spake2-confirmation</a> are computed.</p>
   <p>The values <code>A</code> and <code>B</code> used in SPAKE2 are the <a data-link-type="dfn" href="#agent-fingerprint" id="ref-for-agent-fingerprint②">agent fingerprints</a> of the
client and server, respectively. <code>K</code> is the PSK presented to the user. <code>S</code> and <code>T</code> from SPAKE2 are put into the <code>random</code> field of <a data-link-type="dfn">auth-spake2-handshake</a>. <code>F</code> from SPAKE2 is put into the <code>transcript-mac</code> field of <a data-link-type="dfn">auth-spake2-confirmation</a>.</p>
   <p>If the PSK presenter wants to authenticate, the PSK presenter starts the
authentication process by presenting the PSK to the user and sending a <a data-link-type="dfn">auth-spake2-handshake</a> message. When the PSK consumer receives the <a data-link-type="dfn">auth-spake2-handshake</a> message, the PSK consumer prompts the user for the PSK input
if it has not done so yet.</p>
   <p>If the PSK consumer wants to authenticate, the PSK consumer sends a <a data-link-type="dfn">auth-spake2-need-psk</a> message to the PSK presenter to start the authentication
process and prompts the user to input the PSK. If the PSK presenter receives a <a data-link-type="dfn">auth-spake2-need-psk</a> message after starting authentication from their side, the
PSK presenter ignores the <a data-link-type="dfn">auth-spake2-need-psk</a> message.</p>
   <p>After the user inputs the PSK into the PSK consumer, the PSK consumer computes
and sends a <a data-link-type="dfn">auth-spake2-handshake</a>.</p>
   <p>When either agent both knows the PSK and has received a <a data-link-type="dfn">auth-spake2-handshake</a> message, the agent computes and sends a <a data-link-type="dfn">auth-spake2-confirmation</a> message.</p>
   <p>When either agent has received both <a data-link-type="dfn">auth-spake2-handshake</a> and <a data-link-type="dfn">auth-spake2-confirmation</a> messages, the agent validates the confirmation message
and sends the <a data-link-type="dfn">auth-status</a> authenticated message.</p>
   <h2 class="heading settled" data-level="7" id="presentation-protocol"><span class="secno">7. </span><span class="content">Presentation Protocol</span><a class="self-link" href="#presentation-protocol"></a></h2>
   <p>This section defines the use of the Open Screen Protocol for starting,
terminating, and controlling presentations as defined by <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a>. <a href="#presentation-api">§ 7.1 Presentation API</a> defines how APIs in <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a> map to the
protocol messages defined in this section.</p>
   <p>To learn which receivers are <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-available-presentation-display" id="ref-for-dfn-available-presentation-display">available presentation displays</a> for a
particular <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-request-url" id="ref-for-dfn-presentation-request-url④">presentation request URL</a> or set of URLs, the controller may send
a <a data-link-type="dfn">presentation-url-availability-request</a> message with the following values:</p>
   <dl>
    <dt data-md>urls
    <dd data-md>
     <p>A list of presentation URLs.  Must not be empty.</p>
    <dt data-md>watch-duration
    <dd data-md>
     <p>The period of time that the controller is interested in receiving updates
about their URLs, should the availability change.</p>
    <dt data-md>watch-id
    <dd data-md>
     <p>An identifier the receiver must use when sending updates about URL
availability so that the controller knows which URLs the receiver is referring
to.</p>
   </dl>
   <p>In response, the receiver should send one <a data-link-type="dfn">presentation-url-availability-response</a> message with the following values:</p>
   <dl>
    <dt data-md>url-availabilities
    <dd data-md>
     <p>A list of URL availability states.  Each state must correspond to the matching URL
from the request by list index.</p>
   </dl>
   <p>While the watch is valid (the watch-duration has not expired), the receivers
should send <a data-link-type="dfn">presentation-url-availability-event</a> messages when URL
availabilities change.  Such events contain the following values:</p>
   <dl>
    <dt data-md>watch-id
    <dd data-md>
     <p>The watch-id given in the <a data-link-type="dfn">presentation-url-availability-response</a>,
used to refer to the presentation URLs whose availability has changed.</p>
    <dt data-md>url-availabilities
    <dd data-md>
     <p>A list of URL availability states.  Each state must correspond to the URLs from the
request referred to by the watch-id.</p>
   </dl>
   <p>Note that these messages are not broadcasted to all controllers. They are sent
individually to controllers that have requested availability for the URLs that
have changed in availability state within the watch duration of the original
availability request.</p>
   <p>To save power, the controller may disconnect the QUIC connection and
later reconnect to send availability requests and receive availability
responses and updates.  The QUIC connection ID may or may not be the same
when reconnecting.</p>
   <p>To start a presentation, the controller may send a <a data-link-type="dfn">presentation-start-request</a> message to the receiver with the following
values:</p>
   <dl>
    <dt data-md>presentation-id
    <dd data-md>
     <p>The presentation identifier</p>
    <dt data-md>url
    <dd data-md>
     <p>The selected presentation URL</p>
    <dt data-md>headers
    <dd data-md>
     <p>headers that the receiver should use to fetch the presentation URL.  For example, <a href="https://www.w3.org/TR/presentation-api/#establishing-a-presentation-connection">section 6.6.1</a> of
the Presentation API says that the Accept-Language header should be
provided.</p>
   </dl>
   <p>The presentation ID must follow the restrictions defined by <a href="https://www.w3.org/TR/presentation-api/#common-idioms">section 6.1</a> of the Presentation API, in that
it must consist of at least 16 ASCII characters.</p>
   <p>When the receiver receives the <a data-link-type="dfn">presentation-start-request</a>, it should send back a <a data-link-type="dfn">presentation-start-response</a> message after either the presentation URL has been
fetched and loaded, or the receiver has failed to do so. If it has failed, it
must respond with the appropriate result (such as invalid-url or timeout).  If
it has succeeded, it must reply with a success result.</p>
   <p>Additionally, the response must include the following:</p>
   <dl>
    <dt data-md>connection-id
    <dd data-md>
     <p>An ID that both agents can use to send connection messages
to each other.  It is chosen by the receiver for ease of implementation: if
the message receiver chooses the connection-id, it may keep the ID unique
across connections, thus making message demuxing/routing easier.</p>
   </dl>
   <p>The response should include the following:</p>
   <dl>
    <dt data-md>http-response-code
    <dd data-md>
     <p>The numeric HTTP response code that was returned from fetching the
presentation URL (after redirects).</p>
   </dl>
   <p>To send a presentation message, the controller or receiver may send a <a data-link-type="dfn">presentation-connection-message</a> with the following values:</p>
   <dl>
    <dt data-md>connection-id
    <dd data-md>
     <p>The ID from the <a data-link-type="dfn">presentation-start-response</a> or <a data-link-type="dfn">presentation-connection-open-response</a> messages.</p>
    <dt data-md>message
    <dd data-md>
     <p>The presentation message data.</p>
   </dl>
   <p>To terminate a presentation, the controller may send a <a data-link-type="dfn">presentation-termination-request</a> message with the following values:</p>
   <dl>
    <dt data-md>presentation-id
    <dd data-md>
     <p>The ID of the presentation to terminate.</p>
    <dt data-md>reason
    <dd data-md>
     <p>Set to <code>application-request</code> if the application requested termination,
or <code>user-request</code> if the user requested termination. (These are the only
valid values for <code>reason</code> in a <a data-link-type="dfn">presentation-termination-request</a>.)</p>
   </dl>
   <p>When a <a data-link-type="dfn" href="#receiver" id="ref-for-receiver③">receiver</a> receives a <a data-link-type="dfn">presentation-termination-request</a>, it should
send back a <a data-link-type="dfn">presentation-termination-response</a> message to the requesting
controller.</p>
   <p>It should also notify other controllers about the termination by sending
a <a data-link-type="dfn">presentation-termination-event</a> message.  And it can send the same message if
it terminates a presentation without a request from a controller to do so. This
message contains the following values:</p>
   <dl>
    <dt data-md>presentation-id
    <dd data-md>
     <p>The ID of the presentation that was terminated.</p>
    <dt data-md>source
    <dd data-md>
     <p>Set to <code>controller</code> when the termination was in response to a <a data-link-type="dfn">presentation-termination-request</a>, or <code>receiver</code> otherwise.</p>
    <dt data-md>reason
    <dd data-md>
     <p>The detailed reason why the presentation was terminated.</p>
   </dl>
   <p>To accept incoming connection requests from controller, a receiver must receive
and process the <a data-link-type="dfn">presentation-connection-open-request</a> message which contains the
following values:</p>
   <dl>
    <dt data-md>presentation-id
    <dd data-md>
     <p>The ID of the presentation to connect to.</p>
    <dt data-md>url
    <dd data-md>
     <p>The URL of the presentation to connect to.</p>
   </dl>
   <p>The receiver should, upon receipt of a <a data-link-type="dfn">presentation-connection-open-request</a> message, send back a <a data-link-type="dfn">presentation-connection-open-response</a> message which contains the
following values:</p>
   <dl>
    <dt data-md>result
    <dd data-md>
     <p>a code indicating success or failure, and the reason for the failure</p>
    <dt data-md>connection-id
    <dd data-md>
     <p>An ID that both agents can use to send connection messages
to each other.  It is chosen by the receiver for ease of implementation (if
the message receiver chooses the connection-id, it may keep the ID unique
across connections, thus making message demuxing/routing easier).</p>
    <dt data-md>connection-count
    <dd data-md>
     <p>The new number of open connections to the presentation that received
the incoming connection request.</p>
   </dl>
   <p>If the <a data-link-type="dfn">presentation-connection-open-response</a> message indicates success, the
receiver should also send a <a data-link-type="dfn">presentation-change-event</a> to all other endpoints
that have an active presentation connection to that presentation with the
values:</p>
   <dl>
    <dt data-md>presentation-id
    <dd data-md>
     <p>The ID of the presentation that just received a new presentation connection.</p>
    <dt data-md>connection-count
    <dd data-md>
     <p>The new total number of open connections to that presentation.</p>
   </dl>
   <p>A controller may close a connection without terminating the presentation by
sending a <a data-link-type="dfn">presentation-connection-close-event</a> message to the receiver with the
following values:</p>
   <dl>
    <dt data-md>connection-id
    <dd data-md>
     <p>The ID of the connection that was closed.</p>
    <dt data-md>reason
    <dd data-md>
     <p>Set to <code>close-method-called</code> or <code>connection-object-discarded</code>.</p>
   </dl>
   <p>The receiver may also close a connection without terminating a presentation.  If
it does so, it should send a <a data-link-type="dfn">presentation-connection-close-event</a> message to the
controller with the following values:</p>
   <dl>
    <dt data-md>connection-id
    <dd data-md>
     <p>The ID of the connection that was closed.</p>
    <dt data-md>reason
    <dd data-md>
     <p>Set to <code>close-method-called</code> or <code>connection-object-discarded</code>.</p>
    <dt data-md>connection-count
    <dd data-md>
     <p>The number of open presentation connections that remain.</p>
   </dl>
   <p>If a receiver closes a presentation connection (for any reason), it should send
a <a data-link-type="dfn">presentation-change-event</a> to all other controllers with an open connection
to that presentation with the values:</p>
   <dl>
    <dt data-md>presentation-id
    <dd data-md>
     <p>The ID of the presentation that just closed a connection.</p>
    <dt data-md>connection-count
    <dd data-md>
     <p>The number of open presentation connections that remain.</p>
   </dl>
   <p class="note" role="note"><span>Note:</span> When an agent closes a presentation connection, it is always successful,
so request and response messages are not needed.  A request to terminate a
presentation may succeed or fail, so a response message is required.</p>
   <h3 class="heading settled" data-level="7.1" id="presentation-api"><span class="secno">7.1. </span><span class="content">Presentation API</span><a class="self-link" href="#presentation-api"></a></h3>
   <p>An <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent⑤">Open Screen Protocol agent</a> that is a <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-controlling-user-agent" id="ref-for-dfn-controlling-user-agent①">controlling user agent</a> for the <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a> must support the <code>control-presentation</code> capability.
An <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent⑥">OSP agent</a> that is a <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-receiving-user-agent" id="ref-for-dfn-receiving-user-agent①">receiving user agent</a> for the <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a> must support the <code>receive-presentation</code> capability.
The same OSP agent may be a <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-controlling-user-agent" id="ref-for-dfn-controlling-user-agent②">controlling user agent</a> and a <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-receiving-user-agent" id="ref-for-dfn-receiving-user-agent②">receiving user agent</a>.</p>
   <p class="note" role="note"><span>Note:</span> These roles are independent of which agent was the <a data-link-type="dfn" href="#advertising-agent" id="ref-for-advertising-agent④">advertising agent</a> or the <a data-link-type="dfn" href="#listening-agent" id="ref-for-listening-agent③">listening agent</a> during discovery and connection establishment.</p>
   <p>This is how the <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a> uses the <a href="#presentation-protocol">§ 7 Presentation Protocol</a>:</p>
   <p>When <a href="https://www.w3.org/TR/presentation-api/#the-list-of-available-presentation-displays">section
6.4.2</a> says "This list of presentation displays ... is populated based on an
implementation specific discovery mechanism", the <a data-link-type="dfn" href="#controller" id="ref-for-controller③">controller</a> may
use the mDNS, QUIC, <a data-link-type="dfn">agent-info-request</a>, and <a data-link-type="dfn">presentation-url-availability-request</a> messages defined previously in this spec
to discover receivers.</p>
   <p>When <a href="https://www.w3.org/TR/presentation-api/#the-list-of-available-presentation-displays">section
6.4.2</a> says "To further save power, ... implementation specific discovery of
presentation displays can be resumed or suspended.", the agent may use the
power saving mechanism defined in the previous section.</p>
   <p>When <a href="https://www.w3.org/TR/presentation-api/#starting-a-presentation-connection">section 6.3.4</a> says
"Using an implementation specific mechanism, tell U to create a receiving
browsing context with D, presentationUrl, and I as parameters.", U (the
controller) may send a <a data-link-type="dfn">presentation-start-request</a> message to D
(the receiver), with I for the presentation identifier and presentationUrl for
the selected presentation URL.</p>
   <p class="issue" id="issue-733afe74"><a class="self-link" href="#issue-733afe74"></a> Once the Presentation API has text about
reconnecting via an implementation specific mechanism, quote that here and map
it to a message. <a href="https://github.com/w3c/presentation-api/issues/471">&lt;https://github.com/w3c/presentation-api/issues/471></a></p>
   <p>When <a href="https://www.w3.org/TR/presentation-api/#sending-a-message-through-presentationconnection">section
6.5.2</a> says "Using an implementation specific mechanism, transmit the contents
of messageOrData as the presentation message data and messageType as the
presentation message type to the destination browsing context", the
controller may send a <a data-link-type="dfn">presentation-connection-message</a> with
messageOrData for the presentation message data.  Note that the messageType is
embedded in the encoded CBOR type and does not need an additional value in the
message.</p>
   <p>When <a href="https://www.w3.org/TR/presentation-api/#closing-a-presentationconnection">section 6.5.5</a> says
"Start to signal to the destination browsing context the intention to close the
corresponding PresentationConnection", the agent may send a <a data-link-type="dfn">presentation-connection-close-event</a> message to the other agent with the
destination browsing context and a <a data-link-type="dfn">presentation-change-event</a> when required.</p>
   <p>When <a href="https://www.w3.org/TR/presentation-api/#terminating-a-presentation-in-a-controlling-browsing-context">section
6.5.6</a> says "Send a termination request for the presentation to its receiving
user agent using an implementation specific mechanism", the controller may send
a <a data-link-type="dfn">presentation-termination-request</a> message to the receiver with a <code>reason</code> of <code>application-request</code>.</p>
   <p>When <a href="https://www.w3.org/TR/presentation-api/#monitoring-incoming-presentation-connections">section
6.7.1</a> says "it MUST listen to and accept incoming connection requests from a
controlling browsing context using an implementation specific
mechanism", the receiver must receive and process the <a data-link-type="dfn">presentation-connection-open-request</a>.</p>
   <p>When <a href="https://www.w3.org/TR/presentation-api/#monitoring-incoming-presentation-connections">section
6.7.1</a> says "Establish the connection between the controlling and receiving
browsing contexts using an implementation specific mechanism.", the receiver
must send a <a data-link-type="dfn">presentation-connection-open-response</a> message and <a data-link-type="dfn">presentation-change-event</a> messages when required.</p>
   <h2 class="heading settled" data-level="8" id="remote-playback-protocol"><span class="secno">8. </span><span class="content">Remote Playback Protocol</span><a class="self-link" href="#remote-playback-protocol"></a></h2>
   <p>This section defines the use of the Open Screen Protocol for starting, terminating,
and controlling remote playback of media as defined by the <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a>. <a href="#remote-playback-api">§ 8.2 Remote Playback API</a> defines how
APIs in <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> map to the protocol messages
defined in this section.</p>
   <p>For all messages defined in this section, see Appendix A for the full
CDDL definitions.</p>
   <p class="issue" id="issue-649c173f"><a class="self-link" href="#issue-649c173f"></a> Refinements to Remote Playback protocol. <a href="https://github.com/w3c/openscreenprotocol/issues/159">&lt;https://github.com/w3c/openscreenprotocol/issues/159></a></p>
   <p>To learn which receivers are <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-compatible-remote-playback-device" id="ref-for-dfn-compatible-remote-playback-device">compatible remote playback devices</a> for a
particular URL or set of URLs, the controller may send a <a data-link-type="dfn">remote-playback-availability-request</a> message with the following values:</p>
   <dl>
    <dt data-md>sources
    <dd data-md>
     <p>A list of <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources">media resources</a>, the same as specified in the <a data-link-type="dfn">remote-playback-start-request</a> message.  Must not be empty.</p>
   </dl>
   <p class="issue" id="issue-9145071e"><a class="self-link" href="#issue-9145071e"></a> Remote Playback HTTP headers. <a href="https://github.com/w3c/openscreenprotocol/issues/146">&lt;https://github.com/w3c/openscreenprotocol/issues/146></a></p>
   <dl>
    <dt data-md>headers
    <dd data-md>
     <p>headers that the receiver should use to fetch the
urls.  For example, <a href="https://www.w3.org/TR/remote-playback/#establishing-a-connection-with-a-remote-playback-device">section 6.2.4 of
the Remote Playback API</a> says that the Accept-Language header should be
provided.</p>
    <dt data-md>watch-duration
    <dd data-md>
     <p>The period of time that the controller is interested in receiving updates
about their URLs, should the availability change.</p>
    <dt data-md>watch-id
    <dd data-md>
     <p>An identifier the receiver must use when sending updates about URL
availability so that the controller knows which URLs the receiver is referring
to.</p>
   </dl>
   <p>In response, the receiver should send a <a data-link-type="dfn">remote-playback-availability-response</a> message with the following values:</p>
   <dl>
    <dt data-md>url-availabilities
    <dd data-md>
     <p>A list of URL availability states.  Each state must correspond to the matching URL
from the request by list index.</p>
   </dl>
   <p>The receivers should later (up to the current time plus request
watch-duration) send <a data-link-type="dfn">remote-playback-availability-event</a> messages if
URL availabilities change.  Such events contain the following values:</p>
   <dl>
    <dt data-md>watch-id
    <dd data-md>
     <p>The watch-id given in the <a data-link-type="dfn">remote-playback-availability-response</a> used to refer to the remote playback URLs whose availability has changed.</p>
    <dt data-md>url-availabilities
    <dd data-md>
     <p>A list of URL availability states.  Each state must correspond to the URLs from the
request referred to by the watch-id.</p>
   </dl>
   <p>Note that these messages are not broadcasted to all controllers. They are sent
individually to controllers that have requested availability for the URLs that
have changed in availability state within the watch duration of the original
availability request.</p>
   <p>To save power, the controller may disconnect the QUIC connection and
later reconnect to send availability requests and receive availability
responses and updates. The QUIC connection ID may or may not be the same
when reconnecting.</p>
   <p>To start remote playback, the controller may send a <a data-link-type="dfn">remote-playback-start-request</a> message to the receiver with the following
values:</p>
   <dl>
    <dt data-md>remote-playback-id
    <dd data-md>
     <p>An identifier for this remote playback.  It should be universally unique
among all remote playbacks.</p>
   </dl>
   <p class="note" role="note"><span>Note:</span> A version 4 (pseudorandom) <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc4122#section-4.4" id="ref-for-section-4.4">UUID</a> is recommended as it meets the
requirements for a remote-playback-id.</p>
   <dl>
    <dt data-md>sources
    <dd data-md>
     <p>The <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources①">media resources</a> that the controller has selected for playback
on the receiver.  Each source must include a <code><a data-link-type="element-sub" href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-source-src" id="ref-for-attr-source-src">source URL</a></code> and should include an <code><a data-link-type="element-sub" href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-source-type" id="ref-for-attr-source-type">extended MIME type</a></code>.</p>
    <dt data-md>text-track-urls
    <dd data-md>
     <p>URLs of text tracks associated with the <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources②">media resources</a>.</p>
    <dt data-md>controls
    <dd data-md>
     <p>Initial controls for modifying the initial state of the remote playback, as
defined in <a href="#remote-playback-state-and-controls">§ 8.1 Remote Playback State and Controls</a>.  The controller may send
controls that are optional for the receiver to support before it knows the
receiver supports them.  If the receiver does not support them, it will
ignore them and the controller will learn that it does not support them from
the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>remoting (optional)
    <dd data-md>
     <p>Parameters for starting a streaming session associated with this
remote playback.  If not included, no streaming session is started.</p>
   </dl>
   <p>When the receiver receives a <a data-link-type="dfn">remote-playback-start-request</a> message, it should
send back a <a data-link-type="dfn">remote-playback-start-response</a> message.  It should do so quickly,
usually before the <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources③">media resource</a> has been loaded and instead give updates
of the progress of  loading with <a data-link-type="dfn">remote-playback-state-event</a> messages, unless
the receiver decides to not attempt to load the resource at all.  If it chooses
not to, it must respond with the appropriate failure result (such as timeout or
invalid-url).  Additionally, the response must include the following:</p>
   <dl>
    <dt data-md>state
    <dd data-md>
     <p>The initial state of the remote playback, as defined in <a href="#remote-playback-state-and-controls">§ 8.1 Remote Playback State and Controls</a>.</p>
    <dt data-md>remoting (optional)
    <dd data-md>
     <p>A response to the started streaming session associated with this remote playback.
If not included, no streaming session is started.</p>
   </dl>
   <p>If a streaming session is started, streaming messages such a <a data-link-type="dfn">streaming-session-modify-request</a> and <a data-link-type="dfn">video-frame</a> can be used for the
streaming session as if the streaming session had been started with <a data-link-type="dfn">streaming-session-start-request</a> and <a data-link-type="dfn">streaming-session-start-response</a>. The streaming session may be terminated
before the remote playback is terminated, but if the remote playback is
terminated first, the streaming session associated with it is automatically
terminated.</p>
   <p>If the controller wishes to modify the state of the remote playback (for
example, to pause, resume, skip, etc), it may send a <a data-link-type="dfn">remote-playback-modify-request</a> message with the following values:</p>
   <dl>
    <dt data-md>remote-playback-id
    <dd data-md>
     <p>The ID of the remote playback to be modified.</p>
    <dt data-md>controls
    <dd data-md>
     <p>Updated controls as defined in <a href="#remote-playback-state-and-controls">§ 8.1 Remote Playback State and Controls</a>.</p>
   </dl>
   <p>When a receiver receives a <a data-link-type="dfn">remote-playback-modify-request</a> it should send a <a data-link-type="dfn">remote-playback-modify-response</a> message in reply with the following values:</p>
   <dl>
    <dt data-md>state
    <dd data-md>
     <p>The updated state of the remote playback as defined in <a href="#remote-playback-state-and-controls">§ 8.1 Remote Playback State and Controls</a>.</p>
   </dl>
   <p>When the state of remote playback changes without request for modification from
the controller (such as when the skips or pauses due to user user interaction on
the receiver), the receiver may send a <a data-link-type="dfn">remote-playback-state-event</a> to the
controller.</p>
   <p>The receiver should send a <a data-link-type="dfn">remote-playback-state-event</a> message whenever:</p>
   <p>Any of the following methods are called:</p>
   <ul>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-fastseek">HtmlMediaElement.fastSeek()</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-pause">HtmlMediaElement.pause()</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-play">HtmlMediaElement.play()</a></p>
   </ul>
   <p>Any of the following attributes observably change since the last sent <a data-link-type="dfn">remote-playback-state-event</a> message:</p>
   <ul>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-currentsrc">HtmlMediaElement.currentSrc</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-networkstate">HtmlMediaElement.networkState</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-readystate">HtmlMediaElement.readyState</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-error">HtmlMediaElement.error</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#timeline-offset">HtmlMediaElement’s timeline offset</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-duration">HtmlMediaElement.duration</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-buffered">HtmlMediaElement.buffered</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-seekable">HtmlMediaElement.seekable</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-playbackrate">HtmlMediaElement.playbackRate</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-paused">HtmlMediaElement.paused</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-seeking">HtmlMediaElement.seeking</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#event-media-stalled">HtmlMediaElement.stalled</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-ended">HtmlMediaElement.ended</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-volume">HtmlMediaElement.volume</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-muted">HtmlMediaElement.muted</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videowidth">HtmlMediaElement.videoWidth</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videoheight">HtmlMediaElement.videoHeight</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-audiotracks">HtmlMediaElement.audioTracks</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videotracks">HtmlMediaElement.videoTracks</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videotracks">HtmlMediaElement.textTracks</a></p>
   </ul>
   <p>More than 350ms pass since the last <a data-link-type="dfn">remote-playback-state-event</a> message
  and any of the following attributes observably change since the last <a data-link-type="dfn">remote-playback-state-event</a> message. Any new continuously changing
  attributes fall under this rule.</p>
   <ul>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-played">HtmlMediaElement.played</a></p>
    <li data-md>
     <p><a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-currenttime">HtmlMediaElement.currentTime</a></p>
   </ul>
   <dl>
    <dt data-md>remote-playback-id
    <dd data-md>
     <p>The ID of the remote playback whose state has changed.</p>
    <dt data-md>state
    <dd data-md>
     <p>The updated state of the remote playback, as defined in <a href="#remote-playback-state-and-controls">§ 8.1 Remote Playback State and Controls</a>.</p>
   </dl>
   <p>To terminate the remote playback, the controller may send a <a data-link-type="dfn">remote-playback-termination-request</a> message with the following values:</p>
   <dl>
    <dt data-md>remote-playback-id
    <dd data-md>
     <p>The ID of the remote playback to terminate.</p>
    <dt data-md>reason
    <dd data-md>
     <p>The reason the remote playback is being terminated.</p>
   </dl>
   <p>When a receiver receives a <a data-link-type="dfn">remote-playback-termination-request</a>, it should
send back a <a data-link-type="dfn">remote-playback-termination-response</a> message to the controller.</p>
   <p>If a receiver terminates a remote playback without a request from the controller
to do so, it must send a <a data-link-type="dfn">remote-playback-termination-event</a> message to the
controller with the following values:</p>
   <dl>
    <dt data-md>remote-playback-id
    <dd data-md>
     <p>The ID of the remote playback that was terminated.</p>
    <dt data-md>reason
    <dd data-md>
     <p>The reason the remote playback was terminated.</p>
   </dl>
   <p>As mentioned in <a href="https://www.w3.org/TR/remote-playback/#disconnecting-from-a-remote-playback-device">Remote Playback
API section 6.2.7</a>, terminating the remote playback means the controller is no
longer controlling the remote playback and does not necessarily stop media from
rendering on the receiver.  Whether or not the receiver stops rendering media depends
upon the implementation of the receiver.</p>
   <h3 class="heading settled" data-level="8.1" id="remote-playback-state-and-controls"><span class="secno">8.1. </span><span class="content">Remote Playback State and Controls</span><a class="self-link" href="#remote-playback-state-and-controls"></a></h3>
   <p>In order for the controller and receiver to stay in sync with regards to the
state of the remote playback, the controller may send controls to modify the state
(for example, via the <a data-link-type="dfn">remote-playback-modify-request</a> message) and the receiver
may send updates about state changes (for example, via the <a data-link-type="dfn">remote-playback-state-event</a> message).</p>
   <p>The controls sent by the controller include the following individual control
values, each of which is optional.  This allows the controller to change one
control value or many control values at once without having to specify all
control values every time.  A non-present control value indicates no change.  A
present control value indicates the change defined below. These controls
intentionally mirror settable attributes and methods of the <a href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement" id="termref-for-">HtmlMediaElement</a>.</p>
   <dl>
    <dt data-md>source-url
    <dd data-md>
     <p>Change the <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources④">media resource</a> URL. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-src">HtmlMediaElement.src</a> for more details. Must not be used in the initial controls of the <a data-link-type="dfn">remote-playback-start-request</a> message (which already contains a list of URLs).</p>
    <dt data-md>preload
    <dd data-md>
     <p>Set how aggressively to preload media. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-preload">HtmlMediaElement.preload</a> for more details. Should only be used in the initial controls of the <a data-link-type="dfn">remote-playback-start-request</a> message or when the source is changed.  If not
set in the initial controls, it is left to the receiver to decide.  This is
optional for the receiver to support and if not supported, the receiver will
behave as though it were never set.</p>
    <dt data-md>loop
    <dd data-md>
     <p>Set whether or not to loop media. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-loop">HtmlMediaElement.loop</a> for more details. Should only be used in the initial control of the <a data-link-type="dfn">remote-playback-start-request</a>.  If not set in the initial controls, it is
assumed to be false.</p>
    <dt data-md>paused
    <dd data-md>
     <p>If true, pause; if false, resume. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-pause">HtmlMediaElement.pause()</a>.
and <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-play">HtmlMediaElement.play()</a> for more details.  If not set in the initial controls, it is left to the
receiver to decide.</p>
    <dt data-md>muted
    <dd data-md>
     <p>If true, mute; if false, unmute. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-muted">HtmlMediaElement.muted</a> for more details.  If not set in the initial controls, it is left to the
receiver to decide.</p>
    <dt data-md>volume
    <dd data-md>
     <p>Set the audio volume in the range from 0.0 to 1.0 inclusive. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-volume">HtmlMediaElement.volume</a> for more details.  If not set in the initial controls, it is left to the
receiver to decide.</p>
    <dt data-md>seek
    <dd data-md>
     <p>Seek to a precise time. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-currenttime">HtmlMediaElement.currentTime</a> for more details.</p>
    <dt data-md>fast-seek
    <dd data-md>
     <p>Seek to an approximate time as fast as possible. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-fastseek">HtmlMediaElement.fastSeek()</a> for more details.</p>
    <dt data-md>playback-rate
    <dd data-md>
     <p>Set the rate a which the media plays. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-playbackrate">HtmlMediaElement.playbackRate</a> for more details.  If not set in the initial controls, it is left to the
receiver to decide.  This is optional for the receiver to support and if not
supported, the receiver will behave as though it were never set.</p>
    <dt data-md>poster
    <dd data-md>
     <p>Set the URL of an image to show when video data is not available. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-poster">HtmlMediaElement.poster</a> for more details. If not set in the initial controls, no poster is used and
the receiver can choose what to render when video data is unavailable.  This
is optional for the receiver to support and if not supported, the receiver
will behave as though it were never set.</p>
    <dt data-md>enabled-audio-track-ids
    <dd data-md>
     <p>Enable included audio tracks by ID and disable all other audio tracks. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-audiotracks">HtmlMediaElement.audioTracks</a> for more details.</p>
    <dt data-md>selected-video-track-id
    <dd data-md>
     <p>Select the given video track by ID and unselect all other video tracks. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videotracks">HtmlMediaElement.videoTracks</a> for more details.</p>
    <dt data-md>added-text-tracks
    <dd data-md>
     <p>Add text tracks with the given kinds, labels, and languages. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-addtexttrack">HtmlMediaElement.addTextTrack</a> for more details.  This is optional for the receiver to support and if not
supported, the receiver will behave as though it were never set.</p>
    <dt data-md>changed-text-tracks
    <dd data-md>
     <p>Change text tracks by ID.  All other text tracks are left
unchanged.  Set the mode, add cues, and remove cues by id. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-texttracks">HtmlMediaElement.textTracks</a> for more details.  Note that future specifications or extensions to this
specifications are expected to add new fields to the <a data-link-type="dfn">text-track-cue</a> (such as text size, alignment, position, etc).  Adding and removing
cues is optional for the receiver to support and if not supported, the
receiver will behave as though no cues were added or removed (both adding
and removing are indicated via the support for "added-cues").  As specified in <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-texttracks">HtmlMediaElement.textTracks</a>,
if a cue ID is invalid (removing an un-added ID or adding an ID twice, for example),
the receiver may reject the text track change.</p>
   </dl>
   <div class="note" role="note">
    <table>
     <tbody>
      <tr>
       <th>Field
       <th>Default value for the initial controls
       <th>Receiver support
      <tr>
       <td>source
       <td><code>urls</code> in <a data-link-type="dfn">remote-playback-start-request</a>
       <td>Required
      <tr>
       <td>preload
       <td>Decided by the receiver
       <td>Not required
      <tr>
       <td>loop
       <td>False
       <td>Required
      <tr>
       <td>paused
       <td>Decided by the receiver
       <td>Required
      <tr>
       <td>muted
       <td>Decided by the receiver
       <td>Required
      <tr>
       <td>volume
       <td>Decided by the receiver
       <td>Required
      <tr>
       <td>seek
       <td>(None)
       <td>Required
      <tr>
       <td>fast-seek
       <td>(None)
       <td>Required
      <tr>
       <td>playback-rate
       <td>Decided by the receiver
       <td>Not required
      <tr>
       <td>poster
       <td>Decided by the receiver
       <td>Not required
      <tr>
       <td>enabled-audio-track-ids
       <td>(None)
       <td>Required
      <tr>
       <td>selected-video-track-id
       <td>(None)
       <td>Required
      <tr>
       <td>added-text-tracks
       <td>(None)
       <td>Not required
      <tr>
       <td>changed-text-tracks
       <td>(None)
       <td>Not required
    </table>
   </div>
   <p>The states sent by the receiver include the following individual state values,
each of which is optional.  This allows the receiver to update the controller
about more than one state value at once without having to specify all
state values every time.  A non-present state value indicates the state has not
changed.</p>
   <dl>
    <dt data-md>supports
    <dd data-md>
     <p>The controls the receiver supports.  These may differ for different <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources⑤">media
resource</a>s and should not changes unless the <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources⑥">media resource</a> changes.
The default is empty (support for nothing)
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>source-url
    <dd data-md>
     <p>The current <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources⑦">media resource</a> URL. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-currentsrc">HtmlMediaElement.currentSrc</a>.
Must be present in the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>loading
    <dd data-md>
     <p>The state of network activity for loading the <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-media-resources" id="ref-for-dfn-media-resources⑧">media resource</a>. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-networkstate">HtmlMediaElement.networkState</a>.
The default is empty (NETWORK_EMPTY)
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>loaded
    <dd data-md>
     <p>The state of the loaded media (whether enough is loaded to play). See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-readystate">HtmlMediaElement.readyState</a>.
The default is nothing (HAVE_NOTHING)
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>error
    <dd data-md>
     <p>A major error occurred which prevents the remote playback from continuing. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-error">HtmlMediaElement.error</a> and <a href="https://html.spec.whatwg.org/multipage/media.html#concept-mediaerror-code">HtmlMediaElement media error codes</a>.
The default is no error
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>epoch
    <dd data-md>
     <p>The "zero time" of the media timeline. See <a href="https://html.spec.whatwg.org/multipage/media.html#timeline-offset">HtmlMediaElement’s timeline offset</a> and <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-getstartdate">HtmlMediaElement.getStartDate()</a>.
The default is an unknown epoch
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>duration
    <dd data-md>
     <p>The duration of the media timeline. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-duration">HtmlMediaElement.duration</a>.
The default is an unknown duration
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>buffered-time-ranges
    <dd data-md>
     <p>The time ranges for which media has been buffered. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-buffered">HtmlMediaElement.buffered</a>.
The default is an empty array
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>played-time-ranges
    <dd data-md>
     <p>The time ranges reached by the playback position during normal playback. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-played">HtmlMediaElement.played</a>.
The default is an empty array
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>seekable-time-ranges
    <dd data-md>
     <p>The time ranges for which media is seekable by the controller or the receiver. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-seekable">HtmlMediaElement.seekable</a>.
The default is an empty array
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>position
    <dd data-md>
     <p>The playback position. See <a href="https://html.spec.whatwg.org/multipage/media.html#official-playback-position">HtmlMediaElement’s official playback
position</a> and <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-currenttime">HtmlMediaElement.currentTime</a>.
The default is 0
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>playbackRate
    <dd data-md>
     <p>The current rate of playback on a scale where 1.0 is "normal speed". See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-playbackrate">HtmlMediaElement.playbackRate</a>.
The default is 1.0
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>paused
    <dd data-md>
     <p>Whether media is paused or not. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-paused">HtmlMediaElement.paused</a>.
The default is false
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>seeking
    <dd data-md>
     <p>Whether the receiver is seeking or not. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-seeking">HtmlMediaElement.seeking</a>.
The default is false
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>stalled
    <dd data-md>
     <p>If true, media is not playing because not enough media is loaded, and false otherwise. See <a href="https://html.spec.whatwg.org/multipage/media.html#event-media-stalled">HtmlMediaElement.stalled</a>.
The default is false
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>ended
    <dd data-md>
     <p>Whether media has reached the end or not. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-ended">HtmlMediaElement.ended</a>.
The default is false
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>volume
    <dd data-md>
     <p>The current volume of playback on a scale of 0.0 to 1.0. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-volume">HtmlMediaElement.volume</a>.
The default is 1.0
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>muted
    <dd data-md>
     <p>True if audio is muted (overriding the volume value) and false otherwise.
See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-muted">HtmlMediaElement.muted</a>.
The default is false
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>resolution
    <dd data-md>
     <p>The "intrinsic width" and "intrinsic width" of the video. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videowidth">HtmlMediaElement.videoWidth</a> and <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videoheight">HtmlMediaElement.videoHeight</a>.
The default is unknown
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>audio-tracks
    <dd data-md>
     <p>The available audio tracks, which can individually enabled or disabled. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-audiotracks">HtmlMediaElement.audioTracks</a> The default is an empty array
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>video-tracks
    <dd data-md>
     <p>The available video tracks.  Only one may be selected. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videotracks">HtmlMediaElement.videoTracks</a> The default is an empty array
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
    <dt data-md>text-tracks
    <dd data-md>
     <p>The available text tracks, which can be individually shown, hidden, or disabled. See <a href="https://html.spec.whatwg.org/multipage/media.html#dom-media-videotracks">HtmlMediaElement.textTracks</a>.
The controller can also add cues to and remove cues from text tracks.
The default is an empty array
for the initial state in the <a data-link-type="dfn">remote-playback-start-response</a> message.</p>
   </dl>
   <p>All times, time ranges, and durations (such as position, duration, and
seekable-time-ranges) used above use a common <a data-link-type="dfn">media-time</a> value (see Appendix A)
which includes a time scale.  This allows time values which work on different
time scales to be expressed without loss of precision.  The scale is represented
in hertz, such as 90000 for 90000hz, a common time scale for video.</p>
   <div class="note" role="note">
    <table>
     <tbody>
      <tr>
       <th>Field
       <th>Default value for the initial state
      <tr>
       <td>supports
       <td>Empty
      <tr>
       <td>source
       <td><code>url</code> in <code>state</code> in <a data-link-type="dfn">remote-playback-start-response</a> (required field)
      <tr>
       <td>loading
       <td><code>empty</code>
      <tr>
       <td>loaded
       <td><code>nothing</code>
      <tr>
       <td>error
       <td>No error
      <tr>
       <td>epoch
       <td><code>unknown</code>
      <tr>
       <td>duration
       <td><code>unknown</code>
      <tr>
       <td>buffered-time-ranges
       <td>Empty array
      <tr>
       <td>played-time-ranges
       <td>Empty array
      <tr>
       <td>seekable-time-ranges
       <td>Empty array
      <tr>
       <td>position
       <td>0
      <tr>
       <td>playbackRate
       <td>1.0
      <tr>
       <td>paused
       <td>False
      <tr>
       <td>seeking
       <td>False
      <tr>
       <td>stalled
       <td>False
      <tr>
       <td>ended
       <td>False
      <tr>
       <td>volume
       <td>1.0
      <tr>
       <td>muted
       <td>False
      <tr>
       <td>resolution
       <td><code>unknown</code>
      <tr>
       <td>audio-tracks
       <td>Empty array
      <tr>
       <td>video-tracks
       <td>Empty array
      <tr>
       <td>text-tracks
       <td>Empty array
    </table>
   </div>
   <h3 class="heading settled" data-level="8.2" id="remote-playback-api"><span class="secno">8.2. </span><span class="content">Remote Playback API</span><a class="self-link" href="#remote-playback-api"></a></h3>
   <p>An <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent⑦">Open Screen Protocol agent</a> that implements the <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> must support the <code>control-remote-playback</code> capability.  It may support the <code>send-streaming</code> capability so it can send <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement" id="ref-for-htmlmediaelement⑤">HTMLMediaElement</a></code> media data through media
remoting.</p>
   <p>An an <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent⑧">OSP agent</a> that is a <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-remote-playback-devices" id="ref-for-dfn-remote-playback-devices①">remote playback device</a> for the <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> must support the <code>receive-remote-playback</code> capability.  It may support the <code>receive-streaming</code> capability so it can receive <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement" id="ref-for-htmlmediaelement⑥">HTMLMediaElement</a></code> data through media remoting.</p>
   <p>The same OSP agent may implement both the <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> and be a <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-remote-playback-devices" id="ref-for-dfn-remote-playback-devices②">remote playback device</a> for that API.</p>
   <p class="note" role="note"><span>Note:</span> These roles are independent of which agent was the <a data-link-type="dfn" href="#advertising-agent" id="ref-for-advertising-agent⑤">advertising agent</a> or the <a data-link-type="dfn" href="#listening-agent" id="ref-for-listening-agent④">listening agent</a> during discovery and connection establishment.</p>
   <p>This is how the <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> uses the
messages defined in <a href="#remote-playback-protocol">§ 8 Remote Playback Protocol</a>:</p>
   <p>When <a href="https://www.w3.org/TR/remote-playback/#the-list-of-available-remote-playback-devices">section
6.2.1.2</a> says "This list contains <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-remote-playback-devices" id="ref-for-dfn-remote-playback-devices③">remote playback devices</a> and is populated
based on an implementation specific discovery mechanism" and <a href="https://www.w3.org/TR/remote-playback/#the-list-of-available-remote-playback-devices">section
6.2.1.4</a> says "Retrieve available remote playback devices (using an
implementation specific mechanism)", the user agent may use the mDNS, QUIC, <a data-link-type="dfn">agent-info-request</a>, and <a data-link-type="dfn">remote-playback-availability-request</a> messages
defined previously in this spec to discover <a data-link-type="dfn" href="#receiver" id="ref-for-receiver④">receivers</a>.  The <a data-link-type="dfn">remote-playback-availability-request</a> URLs must contain the <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-availability-sources-set" id="ref-for-dfn-availability-sources-set">availability
sources set</a>.</p>
   <p>When <a href="https://www.w3.org/TR/remote-playback/#establishing-a-connection-with-a-remote-playback-device">section
6.2.4</a> says "Request connection of remote to device. The implementation of this
step is specific to the user agent." and "Synchronize the current media element
state with the remote playback state", the controller may send the <a data-link-type="dfn">remote-playback-start-request</a> message to the receiver to start remote
playback.  The <a data-link-type="dfn">remote-playback-start-request</a> URLs must contain the <a data-link-type="dfn" href="https://w3c.github.io/remote-playback/#dfn-remote-playback-source" id="ref-for-dfn-remote-playback-source">remote
playback source</a>.  The current <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> only
allows a single source, but the protocol allows for several and future versions
of <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> may allow for several.</p>
   <p>When <a href="https://www.w3.org/TR/remote-playback/#establishing-a-connection-with-a-remote-playback-device">section
6.2.4</a> says "The mechanism that is used to connect the user agent with the
remote playback device and play the remote playback source is an implementation
choice of the user agent. The connection will likely have to provide a two-way
messaging abstraction capable of carrying media commands to the remote playback
device and receiving media playback state in order to keep the media element
state and remote playback state in sync", the controller may send <a data-link-type="dfn">remote-playback-modify-request</a> messages to the receiver to change the remote playback state
based on changes to the local media element and receive <a data-link-type="dfn">remote-playback-modify-response</a> and <a data-link-type="dfn">remote-playback-state-event</a> messages to
change the local media element based on changes to the remote playback state.</p>
   <p>When <a href="https://www.w3.org/TR/remote-playback/#establishing-a-connection-with-a-remote-playback-device">section
6.2.7</a> says "Request disconnection of remote from the device. The
implementation of this step is specific to the user agent," the controller may
send the <a data-link-type="dfn">remote-playback-termination-request</a> message to the receiver.</p>
   <h2 class="heading settled" data-level="9" id="streaming-protocol"><span class="secno">9. </span><span class="content">Streaming Protocol</span><a class="self-link" href="#streaming-protocol"></a></h2>
   <p>This section defines the use of the Open Screen Protocol for streaming
media from a <a data-link-type="dfn" href="#media-sender" id="ref-for-media-sender">media sender</a> to a <a data-link-type="dfn" href="#media-receiver" id="ref-for-media-receiver">media receiver</a>.</p>
   <p>If an <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent⑨">Open Screen Protocol agent</a> is a media sender, it must advertise the <code>send-streaming</code> capability.  If an OSP agent is a media receiver, it must
advertise the <code>receive-streaming</code> capability.  The same agent may be a media
sender and a media receiver.</p>
   <p class="note" role="note"><span>Note:</span> These roles are independent of which agent was the <a data-link-type="dfn" href="#advertising-agent" id="ref-for-advertising-agent⑥">advertising agent</a> or the <a data-link-type="dfn" href="#listening-agent" id="ref-for-listening-agent⑤">listening agent</a> during discovery and connection establishment.</p>
   <h3 class="heading settled" data-level="9.1" id="streaming-protocol-capabilities"><span class="secno">9.1. </span><span class="content">Streaming Protocol Capabilities</span><a class="self-link" href="#streaming-protocol-capabilities"></a></h3>
    If the advertiser is already authenticated, the requester has the ability to
request additional information by sending an <a data-link-type="dfn">streaming-capabilities-request</a> message, and receive back a <a data-link-type="dfn">streaming-capabilities-response</a> message with the
following fields: 
   <dl>
    <dt data-md>receive-audio (required)
    <dd data-md>
     <p>A list of capabilities for receiving audio. For an explanation of fields, see below.</p>
    <dt data-md>receive-video (required)
    <dd data-md>
     <p>A list of capabilities for receiving video. For an explanation of fields, see below.</p>
   </dl>
   <p>The format type is used as the basis for audio and video capabilities.
Formats are composed of the following fields:</p>
   <dl>
    <dt data-md>name (required)
    <dd data-md>
     <p>The name of the codec.   This must be a single-codec RFC 6381 <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc6381#section-3" id="ref-for-section-3">codecs parameter</a>.</p>
    <dt data-md>parameters (required)
    <dd data-md>
     <p>A list of (key, value) parameters that can be used to describe
properties of a specific format, and not shared by other formats
of that type (audio, video, etc.).</p>
   </dl>
   <p>Audio capabilities are composed of the above format type, with the following
additional fields:</p>
   <dl>
    <dt data-md>max-audio-channels (optional)
    <dd data-md>
     <p>An optional field indicating the maximum amount of audio
channels the media receiver is capable of supporting. Default value is "2," meaning
a stereo speaker channel setup.</p>
    <dt data-md>min-bit-rate (optional)
    <dd data-md>
     <p>An optional field indicating the minimum audio bit rate that
the media receiver can handle, in kilobits per second. Default is no minimum.</p>
   </dl>
   <p>Video capabilities are similarly composed of the above format type, with the
following additional fields:</p>
   <dl>
    <dt data-md>max-resolution (optional)
    <dd data-md>
     <p>An optional field indicating the maximum video-resolution (width, height)
that the media receiver is capable of processing. Default is no maximum.</p>
    <dt data-md>max-frames-per-second (optional)
    <dd data-md>
     <p>An optional field indicating the maximum frames-per-second the media receiver is
capable of processing. Default is no maximum.</p>
    <dt data-md>max-pixels-per-second (optional)
    <dd data-md>
     <p>An optional field indicating the maximum pixels-per-second the media receiver is
capable of processing, in pixels per second. Default is no maximum.</p>
    <dt data-md>min-video-bit-rate (optional)
    <dd data-md>
     <p>An optional field indicating the minimum video bit rate the device is
capable of processing, in kilobits per second. Default is no minimum.</p>
    <dt data-md>aspect-ratio (optional)
    <dd data-md>
     <p>An optional field indicating what its ideal aspect ratio is, e.g. a 16:10
display could return this value as 1.6 to indicate its preferred content
scaling. Default is none.</p>
    <dt data-md>color-profiles (optional)
    <dd data-md>
     <p>An optional field indicating what color profiles are understood.
The listener may use these values to determine how to encode
video. Some examples include: sRGBv4, Rec709, DciP3. The default value is sRGBv4.</p>
    <dt data-md>native-resolutions (optional)
    <dd data-md>
     <p>An optional field indicating what video-resolutions the media receiver supports and
considers to be "native," meaning that scaling is not required.
The default value is none.</p>
    <dt data-md>supports-scaling (optional)
    <dd data-md>
     <p>An optional boolean field indicating whether the media receiver can scale
content provided in a video-resolution not listed in the native-resolutions
list (if provided) or of a different aspect ratio. The default value is
true.</p>
    <dt data-md>supports-rotation (optional)
    <dd data-md>
     <p>An optional boolean field indicating whether the media receiver can receive
video frames with the rotation field set. The default value is true.</p>
   </dl>
   <h3 class="heading settled" data-level="9.2" id="streaming-sessions"><span class="secno">9.2. </span><span class="content">Sessions</span><a class="self-link" href="#streaming-sessions"></a></h3>
   <p>To start a streaming session, a sender may send a <a data-link-type="dfn">streaming-session-start-request</a> message with the following fields:</p>
   <dl>
    <dt data-md>streaming-session-id
    <dd data-md>
     <p>Identifies the streaming session.  Must be unique for the (sender,
receiver) pair.  Can be used later to modify or terminate a
streaming session.  These IDs should be treated like other IDs
with regards to the <code>state-token</code> as specified in <a href="#requests-responses-watches">§ 10 Requests, Responses, and Watches</a>.</p>
    <dt data-md>desired-stats-interval
    <dd data-md>
     <p>Indicates the frequency the receiver should send stats messages to
the sender.</p>
    <dt data-md>stream-offers
    <dd data-md>
     <p>Indicates the streams that the receiver can request from the sender.</p>
   </dl>
   <p>Each stream offer contains the following fields:</p>
   <dl>
    <dt data-md>media-stream-id
    <dd data-md>
     <p>Identifies the media stream being offered.  Must be unique within
the streaming session.  Can be used by the receiver to request the
media session.  These IDs should be treated like other IDs
with regards to the <code>state-token</code> as specified in <a href="#requests-responses-watches">§ 10 Requests, Responses, and Watches</a>.</p>
    <dt data-md>display-name
    <dd data-md>
     <p>An optional name intended to be shown to a user, such that the
receiver may allow the user to choose which media streams to
receive, or if they are received automatically by the receiver,
give the user some information about what the media stream is.</p>
    <dt data-md>audio
    <dd data-md>
     <p>A list of audio encodings offered.  An audio encoding is a series
of encoded audio frames.  Encodings define fields needed by
the receiver to know how to decode the encoding, such as codec and
sample rate.  They can differ by codec and related fields,
but should be different encodings of the same audio.</p>
    <dt data-md>video
    <dd data-md>
     <p>A list of video encodings offered.  A video encoding is a series of
encoded video frames.  Encodings define fields needed by the
receiver to know how to decode the encoding, such as codec and
default duration.  They can differ by codec and potentially other
fields, but should be different encodings of the same video.</p>
    <dt data-md>data
    <dd data-md>
     <p>A list of data encodings offered.  A data encoding is a series of
data frames.  Encodings define fields needed by the
receiver to know how to interpret the encoding, such as data type and
default duration.  They can differ by data type and potentially other
fields, but should be different encodings of the same data.
(For encodings of different data, use distinct media streams,
 not distinct encodints with the same media stream).</p>
   </dl>
   <p>Each audio encoding offered defines the following fields:</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>Identifies the audio encoding being offered.  Must be unique within
the media stream.  These IDs should be treated like request IDs
with regards to the <code>state-token</code> as specified in <a href="#requests-responses-watches">§ 10 Requests, Responses, and Watches</a>.</p>
    <dt data-md>codec-name
    <dd data-md>
     <p>The name of the codec used by the encoding.  This must be a single-codec
RFC 6381 <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc6381#section-3" id="ref-for-section-3①">codecs parameter</a>.</p>
    <dt data-md>time-scale
    <dd data-md>
     <p>The time scale used by all audio frames.  This allows senders to
make audio-frame messages smaller by not including the time scale
in each one.</p>
    <dt data-md>default-duration:
    <dd data-md>
     <p>The duration of an audio frame.  This allows senders to make
audio-frame messages smaller by not including the duration for
audio-frame messages that have the default duration.</p>
   </dl>
   <p>Each video encoding offered defines the following fields:</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>Identifies the video encoding being offered.  Must be unique within
the media stream.  These IDs should be treated like request IDs
with regards to the <code>state-token</code> as specified in <a href="#requests-responses-watches">§ 10 Requests, Responses, and Watches</a>.</p>
    <dt data-md>codec-name
    <dd data-md>
     <p>The name of the codec used by the encoding.</p>
    <dt data-md>time-scale
    <dd data-md>
     <p>The time scale used by all video frames.  This allows senders to
make video-frame messages smaller by not including the time scale
in each one.</p>
    <dt data-md>default-duration:
    <dd data-md>
     <p>The default duration of a video frame.  This allows senders to make
video-frame messages smaller by not including the duration for
video-frame messages that have the default duration.</p>
    <dt data-md>default-rotation:
    <dd data-md>
     <p>The default rotation of a video frame.  This allows senders to make
video-frame messages smaller by not including the rotation for
video-frame messages that have the default rotation.</p>
   </dl>
   <p>Each data encoding offered defines the following fields:</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>Identifies the data encoding being offered.  Must be unique within
the media stream.  These IDs should be treated like request IDs
with regards to the <code>state-token</code> as specified in <a href="#requests-responses-watches">§ 10 Requests, Responses, and Watches</a>.</p>
    <dt data-md>data-type-name
    <dd data-md>
     <p>The name of the data type used by the encoding.</p>
    <dt data-md>time-scale
    <dd data-md>
     <p>The time scale used by all data frames.  This allows senders to
make data-frame messages smaller by not including the time scale
in each one.</p>
    <dt data-md>default-duration:
    <dd data-md>
     <p>The duration of an data frame .  This allows senders to make
data-frame messages smaller by not including the duration for
data-frame messages that have the default duration.</p>
   </dl>
   <p>After receiving a <a data-link-type="dfn">streaming-session-start-request</a> message, a receiver
should send back a <a data-link-type="dfn">streaming-session-start-response</a> message with the
following fields:</p>
   <dl>
    <dt data-md>desired-stats-interval
    <dd data-md>
     <p>Indicates the frequency the sender should send stats messages to
the receiver.</p>
    <dt data-md>stream-requests
    <dd data-md>
     <p>Indicates which media streams the receiver would like to receive
from the sender.</p>
   </dl>
   <p>Each stream request contains the following fields:</p>
   <dl>
    <dt data-md>media-stream-id
    <dd data-md>
     <p>The ID of the stream reqeusted.</p>
    <dt data-md>audio (optional)
    <dd data-md>
     <p>The requested audio encoding, by encoding ID</p>
    <dt data-md>video (optional)
    <dd data-md>
     <p>The requested video encoding, by encoding ID.  It may
include a target resolution and maximum frame rate.  The sender
should not exceed the maximum frame rate and should attempt to
send at the target bitrate, possibly exceeding it by a small amount.</p>
    <dt data-md>data (optional)
    <dd data-md>
     <p>The requested data encoding, by encoding ID</p>
   </dl>
   <p>During a streaming session, the receiver can modify the requests it
made for encodings by sending a <a data-link-type="dfn">streaming-session-modify-request</a> containing a modified list of stream-requests.  When the sender receives
a <a data-link-type="dfn">streaming-session-modify-request</a>, it should send back a <a data-link-type="dfn">streaming-session-modify-response</a> indicate whether or not the
application of the new request from the <a data-link-type="dfn">streaming-session-modify-request</a> was successful.</p>
   <p>Finally, the sender may terminate the streaming session by sending
a <a data-link-type="dfn">streaming-session-terminate-request</a> command.  When the receiver
receives the <a data-link-type="dfn">streaming-session-terminate-request</a>, it should send back
a <a data-link-type="dfn">streaming-session-terminate-response</a>.  The receiver can terminate at
any point and notify the sender by sending a <a data-link-type="dfn">streaming-session-terminate-event</a> message.</p>
   <h3 class="heading settled" data-level="9.3" id="streaming-audio"><span class="secno">9.3. </span><span class="content">Audio</span><a class="self-link" href="#streaming-audio"></a></h3>
   <p>[Media senders=] may send audio to <a data-link-type="dfn" href="#media-receiver" id="ref-for-media-receiver①">media receivers</a> by sending <a data-link-type="dfn">audio-frame</a> messages (see <a href="#appendix-a">Appendix A: Messages</a>) with the following keys and
values.  An audio frame message contains a set of encoded audio samples for a
range of time. A series of encoded audio frames that share a codec, codec
parameters and a timeline form an audio encoding.</p>
   <p>Unlike most Open Screen Protocol messages, this one uses an
array-based grouping rather than a struct-based grouping.  For
required fields, this allows for a more efficient use of bytes on the
wire, which is important for streaming audio because the payload is
typically so small and every byte of overhead is relatively large.  In
order to accomodate optional values in the array-based grouping, one
optional field in the array is used to hold all optional values in a
struct-based grouping.  This will hopefully provide a good balance of
efficiency and flexibility.</p>
   <p>To allow for audio frames to be sent out of order, they should be sent in
separate QUIC streams.</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>Identifies the media encoding to which this audio frame belongs.  This can be
used to reference fields of the encoding (from the <a data-link-type="dfn">audio-encoding-offer</a> message) such as the codec, codec properties,
time scale (aka clock rate or sample rate), and default duration.
Referencing fields of the encoding through the encoding id
helps to avoid sending duplicate information in every frame.</p>
    <dt data-md>start-time
    <dd data-md>
     <p>Identifies the beginning of the time range of the audio frame. The
end time can be inferred from the start time and duration. The
time scale is equal to the value in the <code>time-scale</code> field of the <a data-link-type="dfn">audio-encoding-offer</a> message referenced by the <code>encoding-id</code>.</p>
    <dt data-md>duration
    <dd data-md>
     <p>If present, the duration of the audio frame. If not present, the
duration is equal to the <code>default-duration</code> field of the <a data-link-type="dfn">audio-encoding-offer</a> message referenced by the <code>encoding-id</code>.
The time scale is equal to the value in the <code>time-scale</code> field of
the <a data-link-type="dfn">audio-encoding-offer</a> message referenced by the <code>encoding-id</code>.</p>
    <dt data-md>sync-time
    <dd data-md>
     <p>If present, a time used to synchronize the start time of this audio frame (and
thus, this encoding) with that of other media encodings on
different timelines.  It may be wall clock time, but it need not
be; it can be any clock chosen by the media sender.</p>
    <dt data-md>payload
    <dd data-md>
     <p>The encoded audio.  The codec and codec parameters are equal to the <code>format</code> field of the <a data-link-type="dfn">audio-encoding-offer</a> message referenced by
the <code>encoding-id</code></p>
   </dl>
   <h3 class="heading settled" data-level="9.4" id="streaming-video"><span class="secno">9.4. </span><span class="content">Video</span><a class="self-link" href="#streaming-video"></a></h3>
   <p>Media senders may send video to media receivers by sending <a data-link-type="dfn">video-frame</a> messages (see <a href="#appendix-a">Appendix A: Messages</a>) with the following keys and values.  A video
frame message contains an encoded video frame (an encoded image) at a specific
point in time or over a specfic time range (if the duration is known).  A series
of encoded video frames that share a codec, codec parameters and a timeline form
a video encoding.</p>
   <p>To allow for video frames to be sent out of order, they may be sent in
separate QUIC streams.  If the encoding is a long chain of encoded video frames
dependent on the previous one back until an independent frame, it may make sense
to send them in a single QUIC stream starting at the indepdendent frame and
ending at the last dependent frame.</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>Identifies the media encoding to which this video frame belongs.
This can be used to reference fields of the encoding such as the
codec, codec properties, time scale, and default rotation.
Referencing fields of the encoding through the encoding id helps
to avoid sending duplicate information in every frame.</p>
    <dt data-md>sequence-number
    <dd data-md>
     <p>Identifies the frame and its order in the encoding.
Within an encoding, larger sequence numbers mean later start times.
Within an encoding, gaps in sequence numbers mean frames are missing.</p>
    <dt data-md>depends-on
    <dd data-md>
     <p>If present, the sequence numbers of the frames this frame depends on.
If a sequence numbers is negative, it is treated as a relative sequence numbers
and the sequence numbers is calculated by adding it to the sequence number of this frame.
If empty, this is an independent frame (a key frame).
If not present, the default value is [-1].</p>
    <dt data-md>start-time
    <dd data-md>
     <p>Identifies the beginning of the time range of the video frame.  The
end time can be inferred from the start time and duration. The
time scale is equal to the value in the <code>time-scale</code> field of the <a data-link-type="dfn">video-encoding-offer</a> message referenced by the <code>encoding-id</code>.</p>
    <dt data-md>duration
    <dd data-md>
     <p>If present, the duration of the video frame. If not present, that
means duration is unknown.  The time scale is equal to the value
in the <code>time-scale</code> field of the <a data-link-type="dfn">video-encoding-offer</a> message
referenced by the <code>encoding-id</code>.</p>
    <dt data-md>sync-time
    <dd data-md>
     <p>If present, a time used to synchronize the start time of this frame (and
thus, this encoding) with that of other media encodings on different
timelines.</p>
    <dt data-md>rotation
    <dd data-md>
     <p>If present, indicates how the frame should be rotated after
decoding but before rendering.  Rotation is clockwise in
increments of 90 degrees.  The default is equal to the <code>default-rotation</code> field of the <a data-link-type="dfn">video-encoding-offer</a> message
referenced by the <code>encoding-id</code>.</p>
    <dt data-md>payload
    <dd data-md>
     <p>The encoded video frame (encoded image).  The codec and codec
 parameters are are equal to the <code>format</code> field of the <a data-link-type="dfn">audio-encoding-offer</a> message referenced by the <code>encoding-id</code>.</p>
   </dl>
   <h3 class="heading settled" data-level="9.5" id="streaming-data"><span class="secno">9.5. </span><span class="content">Data</span><a class="self-link" href="#streaming-data"></a></h3>
   <p>Media senders may send timed data to media receivers by sending <a data-link-type="dfn">data-frame</a> messages (see <a href="#appendix-a">Appendix A: Messages</a>) with the following keys and values.  A data frame message
contains an arbitrary payload that can be synchronized with audio and video.
A series of data frames that share a data type and timeline form a data encoding.</p>
   <p>To allow for data frames to be sent out of order, they may be sent in separate
QUIC streams, but more than one data frame may be sent in one QUIC stream if
that makes sense for a specific type of data.</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>Identifies the data encoding to which this data frame belongs.  This can be
used to reference fields of the encoding such as the type of data and
time scale.  Referencing fields of the encoding through the encoding id
helps to avoid sending duplicate information in every frame.</p>
    <dt data-md>sequence-number
    <dd data-md>
     <p>Identifies the frame and its order in the encoding.
Within an encoding, larger sequence numbers mean later start times.
Within an encoding, gaps in sequence numbers mean frames are missing.</p>
    <dt data-md>start-time
    <dd data-md>
     <p>Identifies the beginning of the time range of the data frame.  The
end time can be inferred from the start time and duration.  The
time scale is equal to the value in the <code>time-scale</code> field of the <a data-link-type="dfn">data-encoding-offer</a> message referenced by the <code>encoding-id</code>.</p>
    <dt data-md>duration
    <dd data-md>
     <p>If present, the duration of the data frame. If not present, the
duration is equal to the <code>default-duration</code> field of the <a data-link-type="dfn">data-encoding-offer</a> message referenced by the <code>encoding-id</code>.
The time scale is equal to the value in the <code>time-scale</code> field of
the <a data-link-type="dfn">data-encoding-offer</a> message referenced by the <code>encoding-id</code>.</p>
    <dt data-md>sync-time
    <dd data-md>
     <p>If present, a time used to synchronize the start time of this data frame (and
thus, this encoding) with that of other media encodings on different
timelines.</p>
    <dt data-md>payload
    <dd data-md>
     <p>The data.  The data type is equal to the <code>data-type</code> field of the
the <a data-link-type="dfn">data-encoding-offer</a> message referenced by the <code>encoding-id</code>.</p>
   </dl>
   <h3 class="heading settled" data-level="9.6" id="streaming-feedback"><span class="secno">9.6. </span><span class="content">Feedback</span><a class="self-link" href="#streaming-feedback"></a></h3>
   <p>The media receiver can send feedback to the media sender, such as key frame
requests.</p>
   <p>A video key frame is requested by sending a video-request message with
the following keys and values.</p>
   <p>To allow for video frames to be sent out of order, they may be sent in separate
QUIC streams.</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>The encoding for which the media sender should send a new key frame.</p>
    <dt data-md>sequence-number
    <dd data-md>
     <p>Gives the order in the encoding.
Within an encoding, larger sequence numbers invalidate previous ones.
A media sender may ignore smaller sequence numbers after a larger one has been processed.
This it to prevent out-of-order requests from generating more key frames than necessary.</p>
    <dt data-md>highest-decoded-frame-sequence-number: uint
    <dd data-md>
     <p>If set, the media sender may generate a video frame dependent on the last decoded
frame.  If not set, the media sender must generate an indepdendent (key) frame.</p>
   </dl>
   <h3 class="heading settled" data-level="9.7" id="streaming-stats"><span class="secno">9.7. </span><span class="content">Stats</span><a class="self-link" href="#streaming-stats"></a></h3>
   <p>During a streaming session, the sender should send stats with the <a data-link-type="dfn">streaming-session-sender-stats-event</a> at the interval the receiver requested.  It
should send all of the following stats for all of the media streams it is
sending. The <a data-link-type="dfn">streaming-session-sender-stats-event</a> message contains the following
fields:</p>
   <dl>
    <dt data-md>streaming-session-id
    <dd data-md>
     <p>The ID of the streaming session these stats apply to.</p>
    <dt data-md>system-time
    <dd data-md>
     <p>The time when the stats were calculated, using a monotonic system
clock.</p>
    <dt data-md>audio
    <dd data-md>
     <p>Stats specific to audio.  Stats for multiple encodings can be sent
at once, but encodings need not be included if the stats haven’t
changed.  See below.</p>
    <dt data-md>video
    <dd data-md>
     <p>Stats specific to video.  Stats for multiple encodings can be sent
at once, but encodings need not be included if the stats haven’t
changed.  See below.</p>
   </dl>
   <p>Audio encoding sender stats include the following fields:</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>The ID of the encoding for which the stats apply.</p>
    <dt data-md>cumulative-sent-frames
    <dd data-md>
     <p>The total number of frames sent.</p>
    <dt data-md>cumulative-encode-delay
    <dd data-md>
     <p>The sum of the time spent encoding frames sent.</p>
   </dl>
   <p>Video encoding sender stats include the following fields:</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>The ID of the encoding for which the stats apply.</p>
    <dt data-md>cumulative-sent-duration
    <dd data-md>
     <p>The sum of all of the durations of all of the audio frames sent.</p>
    <dt data-md>cumulative-encode-delay
    <dd data-md>
     <p>The sum of the time spent encoding frames sent.</p>
    <dt data-md>cumulative-dropped frames
    <dd data-md>
     <p>The total number of frames that were not sent due to network, CPU,
or other contraints.</p>
   </dl>
   <p>During a streaming session, the receiver should send stats with the <a data-link-type="dfn">streaming-session-receiver-stats-event</a> at the interval the sender requested.
It should send all of the following stats for all of the media streams it is
receiving.  The <a data-link-type="dfn">streaming-session-receiver-stats-event</a> message contains the
following fields:</p>
   <dl>
    <dt data-md>streaming-session-id
    <dd data-md>
     <p>The ID of the streaming session these stats apply to.</p>
    <dt data-md>system-time
    <dd data-md>
     <p>The time when the stats were calculated, using a monotonic system
clock.</p>
    <dt data-md>audio
    <dd data-md>
     <p>Stats specific to audio.  Stats for multiple encodings can be sent
at once, but encodings need not be included if the stats haven’t
changed.  See below.</p>
    <dt data-md>video
    <dd data-md>
     <p>Stats specific to video.  Stats for multiple encodings can be sent
at once, but encodings need not be included if the stats haven’t
changed.  See below.</p>
   </dl>
   <p>Audio encoding receiver stats include the following fields.  If not
present, that indicates the value has not changed since the last value.</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>The ID of the encoding for which the stats apply.</p>
    <dt data-md>cumulative-decoded-frames
    <dd data-md>
     <p>The total number of audio frames received and decoded.</p>
    <dt data-md>cumulative-received-duration
    <dd data-md>
     <p>The sum of all of the durations of all of the audio frames received.</p>
    <dt data-md>cumulative-lost-duration
    <dd data-md>
     <p>The sum of all of the durations of all of the audio frames detected as lost.</p>
    <dt data-md>cumulative-buffer-delay
    <dd data-md>
     <p>The sum of the time frames spent buffered between receipt and playout.</p>
    <dt data-md>cumulative-decode-delay
    <dd data-md>
     <p>The sum of the time spent decoding frames received.</p>
   </dl>
   <p>Video encoding receiver stats include the following fields.  If not
present, that indicates the value has not changed since the last
value.</p>
   <dl>
    <dt data-md>encoding-id
    <dd data-md>
     <p>The ID of the encoding for which the stats apply.</p>
    <dt data-md>cumulative-decoded-frames
    <dd data-md>
     <p>The total number of video frames received and decoded.</p>
    <dt data-md>cumulative-lost-frames
    <dd data-md>
     <p>The total number of video frames detected as lost.</p>
    <dt data-md>cumulative-buffer-delay
    <dd data-md>
     <p>The sum of the time frames spent buffered between receipt and render.</p>
    <dt data-md>cumulative-decode-delay
    <dd data-md>
     <p>The sum of the time spent decoding frames received.</p>
   </dl>
   <h2 class="heading settled" data-level="10" id="requests-responses-watches"><span class="secno">10. </span><span class="content">Requests, Responses, and Watches</span><a class="self-link" href="#requests-responses-watches"></a></h2>
   <p>Multiple sub-protocols in the Open Screen Protocol have messages that act as
requests, responses, watches, and events. Most requests have a <code>request-id</code>, and
the agent that receives the request must send exactly one reponse message in
return with the same <code>request-id</code>.  A watch request has a <code>watch-id</code>, and the
agent that receives the request may send any number of event messages in
response with the same <code>watch-id</code>, until the watch request expires.</p>
   <p><code>request-id</code> and <code>watch-id</code> values are unsigned integer IDs that are assigned
from a counter kept by each agent that starts at 1 and increments by 1 for each
ID.  Whenever an agent changes its <code>state-token</code>, it must reset its counter to 1.</p>
   <p>When an agent sees that another agent has reset its state (by virtue of
advertising a new <code>state-token</code>), it should discard any requests, responses,
watches and events for that agent.</p>
   <p>Other IDs that must be unique and would cause confusion if one side
loses state, such as <code>streaming-session-id</code>, <code>media-session-id</code>, and <code>encoding-id</code> should be treated the same.</p>
   <p class="note" role="note"><span>Note:</span> Request and watch IDs are not tied to any particular QUIC connection
between agents.  If a QUIC connection is closed, an agent should not discard
requests, responses, watches, or events related to the other party.  This allows
agents to save power by closing unused connections.</p>
   <p class="note" role="note"><span>Note:</span> Request and watch IDs are not unique across agents.  An agent can combine
a request ID with a unique identifier for the agent that sent it (like its
certificate fingerprint) to track requests across multiple agents.</p>
   <h2 class="heading settled" data-level="11" id="protocol-extensions"><span class="secno">11. </span><span class="content">Protocol Extensions</span><a class="self-link" href="#protocol-extensions"></a></h2>
   <p><a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent①⓪">Open Screen Protocol agents</a> may exchange extension messages that are not
defined by this specification.  This could be used for experimentation,
customization or other purposes.</p>
   <p>To add new extension messages, extension authors must register a capability ID
with a range of message type keys in a <a href="https://w3c.github.io/openscreenprotocol/capabilites.md">public registry</a>.
Agents may then indicate that they accept an extension by including the
corresponding capability ID in the <code>capabilities</code> field of its <a data-link-type="dfn">agent-info</a> message.</p>
   <p>Capability IDs 1-999 are reserved for use by the Open Screen Protocol.
Capability IDs 1000 and above are available for extensions.  See <a href="#appendix-b">Appendix B: Message Type Key Ranges</a> for legal ranges for extension message type keys.</p>
   <p class="note" role="note"><span>Note:</span> The purpose of the public registry is to prevent conflicts between
multiple extension authors' capability IDs and message type keys.</p>
   <p>Agents must not send extension messages to another agent that has not advertised
the corresponding extension capability ID.</p>
   <p class="note" role="note"><span>Note:</span> See <a href="#messages">§ 5 Messages delivery using CBOR and QUIC streams</a> for how agents handle unknown message type keys.</p>
   <p>It is recommended that extension messages are also encoded in CBOR, to simplify
implementations and provide an easier path to standardization of extension
protocols.  However, this is not required; agents that support non-CBOR
extensions must be able to decode QUIC streams that contain a mix of CBOR
messages and non-CBOR extension messages.</p>
   <h3 class="heading settled" data-level="11.1" id="protocol-extension-fields"><span class="secno">11.1. </span><span class="content">Protocol Extension Fields</span><a class="self-link" href="#protocol-extension-fields"></a></h3>
   <p>It is legal for an agent to add additional, extension fields to any map-valued
CBOR message type defined by the Open Screen Protocol.  Extension fields must be
optional, and the Open Screen Protocol message must make sense both with and
without the field set.</p>
   <p>Agents must not add extended fields to the <a data-link-type="dfn">audio-frame</a> message directly.
Instead, they may add them to its nested <code>optional</code> value.</p>
   <p>Extension fields should use string keys to avoid conflicts with integer keys in
Open Screen Protocol messages.  An agent should not send extension fields to
another agent unless that agent advertises an extension capability ID in its <a data-link-type="dfn">agent-info</a> that indicates that it understands the extension fields.</p>
   <h2 class="heading settled" data-level="12" id="security-privacy"><span class="secno">12. </span><span class="content">Security and Privacy</span><a class="self-link" href="#security-privacy"></a></h2>
   <p>The Open Screen Protocol allows two <a data-link-type="dfn" href="#open-screen-protocol-agent" id="ref-for-open-screen-protocol-agent①①">OSP agents</a> to discover each other and
exchange user and application data.  As such, its security and privacy
considerations should be closely examined.  We first evaluate the protocol
itself using the W3C <a data-link-type="biblio" href="#biblio-security-privacy-questionnaire">Security and Privacy
Questionnaire</a>.  We then examine whether the security and privacy guidelines
recommended by the <a data-link-type="biblio" href="#biblio-presentation-api">Presentation API</a> and the <a data-link-type="biblio" href="#biblio-remote-playback">Remote Playback API</a> are met.  Finally we discuss recommended
mitigations that agents can use to meet these security and privacy requirements.</p>
   <h3 class="heading settled" data-level="12.1" id="threat-models"><span class="secno">12.1. </span><span class="content">Threat Models</span><a class="self-link" href="#threat-models"></a></h3>
   <h4 class="heading settled" data-level="12.1.1" id="passive-network-attackers"><span class="secno">12.1.1. </span><span class="content">Passive Network Attackers</span><a class="self-link" href="#passive-network-attackers"></a></h4>
   <p>The Open Screen Protocol should assume that all parties that are connected to
the same LAN, either through a wired connection or through WiFi, are able to
observe all data flowing between OSP agents.</p>
   <p>These parties will be able collect any data exposed through unencrypted
messages, such as mDNS records and the QUIC handshakes.</p>
   <p>These parties may attempt to learn cryptographic parameters by observing data
flows on the QUIC connection, or by observing cryptographic timing.</p>
   <h4 class="heading settled" data-level="12.1.2" id="active-network-attackers"><span class="secno">12.1.2. </span><span class="content">Active Network Attackers</span><a class="self-link" href="#active-network-attackers"></a></h4>
   <p>Active attackers, such as compromised routers, will be able to manipulate data
exchanged between agents.  They can inject traffic into existing QUIC
connections and attempt to initiate new QUIC connections.  These abilities can
be used to attempt the following:</p>
   <ul>
    <li data-md>
     <p>Impersonate an agent or one already authenticated by the user, in an attempt
to convince the user to authenticate to it.</p>
    <li data-md>
     <p>Connect to an agent and query its capabilities.</p>
    <li data-md>
     <p>Connect to and control a presentation or remote playback, or extract data
from the application state of the presentation or remote playback.</p>
   </ul>
   <p>One particular attack of concern is misconfigured or compromised routers that
expose local network devices (such as OSP agents) to the Internet.  This vector
of attack has been used by malicious parties to take control of printers and
smart TVs by connecting to local network services that would normally be
inaccessible from the Internet.</p>
   <h4 class="heading settled" data-level="12.1.3" id="denial-of-service"><span class="secno">12.1.3. </span><span class="content">Denial of Service</span><a class="self-link" href="#denial-of-service"></a></h4>
   <p>Parties with connected to the LAN may attempt to deny access to OSP agents.  For
example, an attacker my attempt to open a large number of QUIC connections to an
agent in an attempt to block legitimate connections or exhaust the agent’s
system resources.  They may also multicast spurious DNS-SD records in an attempt
to exhaust the cache capacity for mDNS listeners, or to get listeners to open a
large number of bogus QUIC connections.</p>
   <h4 class="heading settled" data-level="12.1.4" id="same-origin-policy-violations"><span class="secno">12.1.4. </span><span class="content">Same-Origin Policy Violations</span><a class="self-link" href="#same-origin-policy-violations"></a></h4>
   <p>The Presentation API allows cross-origin communication between controlling pages
and presentations with the consent of each origin (through their use of the
API).  This is similar to cross-origin communication via <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/web-messaging.html#dom-window-postmessage" id="ref-for-dom-window-postmessage">postMessage()</a></code> with a <code>targetOrigin</code> of <code>*</code>.  However, the Presentation API does not convey source
origin information with each message.  Therefore, the Open Screen Protocol does
not convey origin information between its agents.</p>
   <p>The <a data-link-type="dfn" href="https://w3c.github.io/presentation-api/#dfn-presentation-id" id="ref-for-dfn-presentation-id③">presentation ID</a> carries some protection against unrestricted
cross-origin access; but, rigorous authentication of the parties connected by a <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/presentation-api/#presentationconnection" id="ref-for-presentationconnection②">PresentationConnection</a></code> must be done at the application level.</p>
   <h3 class="heading settled" data-level="12.2" id="security-privacy-questions"><span class="secno">12.2. </span><span class="content">Open Screen Protocol Security and Privacy Considerations</span><a class="self-link" href="#security-privacy-questions"></a></h3>
   <h4 class="heading settled" data-level="12.2.1" id="personally-identifiable-information"><span class="secno">12.2.1. </span><span class="content">Personally Identifiable Information &amp; High-Value Data</span><a class="self-link" href="#personally-identifiable-information"></a></h4>
   <p>The following data exchanged by the protocol can be personally identifiable
and/or high value data:</p>
   <ol>
    <li data-md>
     <p>Presentation URLs and availability results</p>
    <li data-md>
     <p>Presentation IDs</p>
    <li data-md>
     <p>Presentation connection IDs</p>
    <li data-md>
     <p>Presentation connection messages</p>
    <li data-md>
     <p>Remote playback URLs</p>
    <li data-md>
     <p>Remote playback commands and status messages</p>
   </ol>
   <p>Presentation IDs are considered high value data because they can be used in
conjunction with a Presentation URL to connect to a running presentation.</p>
   <p>Presentation display names, model names, and capabilities, while not
considered personally identifiable, are important to protect to prevent an
attacker from changing them or substituting other values during the discovery
and authentication process.</p>
   <p>The following data cannot be reasonably made confidential and should be
considered public:</p>
   <ol>
    <li data-md>
     <p>IP addresses and ports used by the Open Screen Protocol.</p>
    <li data-md>
     <p>Data advertised through mDNS, including the display name prefix, the
certificate fingerprint, and the metadata version.</p>
    <li data-md>
     <p>Data provided by an agent through <a data-link-type="dfn">agent-info</a>, including its <a data-link-type="dfn" href="#display-name" id="ref-for-display-name">display name</a>, its device model name, its capabilities, and its
preferred locales.</p>
   </ol>
   <h4 class="heading settled" data-level="12.2.2" id="cross-origin-state"><span class="secno">12.2.2. </span><span class="content">Cross Origin State Considerations</span><a class="self-link" href="#cross-origin-state"></a></h4>
   <p>Access to origin state across browsing sessions is possible through the
Presentation API by reconnecting to a presentation that was started by a
previous session. This scenario is addressed in <a href="https://www.w3.org/TR/presentation-api/#cross-origin-access">Presentation API §cross-origin-access</a>.</p>
   <p>Receiver availability is available cross-origin depending on the user’s network
context.  Exposure of this data to the Web is also discussed in <a href="https://www.w3.org/TR/presentation-api/#personally-identifiable-information">Presentation API §personally-identifiable-information</a> and <a href="https://www.w3.org/TR/remote-playback/#personally-identifiable-information">Remote Playback API §personally-identifiable-information</a>.</p>
   <h4 class="heading settled" data-level="12.2.3" id="origin-access-devices"><span class="secno">12.2.3. </span><span class="content">Origin Access to Other Devices</span><a class="self-link" href="#origin-access-devices"></a></h4>
   <p>By design, the Open Screen Protocol allows access to receivers from the Web.  By
implementing the protocol, these devices are knowingly making themselves
available to the Web and should be designed accordingly.</p>
   <p>Below, we discuss mitigation steps to prevent malicious use of these devices.</p>
   <h4 class="heading settled" data-level="12.2.4" id="incognito-mode"><span class="secno">12.2.4. </span><span class="content">Incognito Mode</span><a class="self-link" href="#incognito-mode"></a></h4>
   <p>The Open Screen Protocol does not distinguish between the user agent’s normal
browsing and incognito modes, and agents that follow the specification
behave identically regardless of which mode is in use.</p>
   <p>It’s recommended that user agents use separate authentication contexts and QUIC
connections for normal and incognito profiles from the same user agent instance.
This prevents OSP agents from correlating activity among profiles
belonging to the same user (both normal and incognito).</p>
   <h4 class="heading settled" data-level="12.2.5" id="persistent-state"><span class="secno">12.2.5. </span><span class="content">Persistent State</span><a class="self-link" href="#persistent-state"></a></h4>
   <p>An agent is likely to persist the identity of agents that have successfully
completed <a href="#authentication">§ 6 Authentication</a>.  This may include the public key fingerprints,
metadata versions, and metadata for those parties.</p>
   <p>However, this data is not normally exposed to the Web, only through the native
UI of the user agent during the display selection or display authentication
process.  It can be an implementation choice whether the user agent clears or
retains this data when the user clears browsing data.</p>
   <p class="issue" id="issue-8bf4aa9f"><a class="self-link" href="#issue-8bf4aa9f"></a> Fate of metadata / authentication history when clearing browsing data. <a href="https://github.com/w3c/openscreenprotocol/issues/132">&lt;https://github.com/w3c/openscreenprotocol/issues/132></a></p>
   <h4 class="heading settled" data-level="12.2.6" id="other-considerations"><span class="secno">12.2.6. </span><span class="content">Other Considerations</span><a class="self-link" href="#other-considerations"></a></h4>
   <p>The Open Screen Protocol does not grant to the Web additional access to the
following:</p>
   <ul>
    <li data-md>
     <p>New script loading mechanisms</p>
    <li data-md>
     <p>Access to the user’s location</p>
    <li data-md>
     <p>Access to device sensors</p>
    <li data-md>
     <p>Access to the user’s local computing environment</p>
    <li data-md>
     <p>Control over the user agent’s native UI</p>
    <li data-md>
     <p>Security characteristics of the user agent</p>
   </ul>
   <h3 class="heading settled" data-level="12.3" id="presentation-api-considerations"><span class="secno">12.3. </span><span class="content">Presentation API Considerations</span><a class="self-link" href="#presentation-api-considerations"></a></h3>
   <p><a href="https://www.w3.org/TR/presentation-api/#security-and-privacy-considerations">Presentation API §security-and-privacy-considerations</a> place these
requirements on the Open Screen Protocol:</p>
   <ol>
    <li data-md>
     <p>Presentation URLs and presentation IDs should remain private among the
parties that are allowed to connect to a presentation, per the
cross-origin access guidelines.</p>
    <li data-md>
     <p>Controllers and receivers should be notified when connections representing
multiple user agent profiles have been made to a presentation, per the user
interface guidelines.</p>
    <li data-md>
     <p>Messaging between controllers and receivers should be authenticated and
confidential, per the guidelines for messaging between presentation
connections.</p>
   </ol>
   <p>The Open Screen Protocol addresses these considerations by:</p>
   <ol>
    <li data-md>
     <p>Requiring mutual authentication and a TLS-secured QUIC connection before
 presentation URLs, IDs, or messages are exchanged.</p>
    <li data-md>
     <p>Adding explicit messages and connection IDs for individual <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/presentation-api/#presentationconnection" id="ref-for-presentationconnection③">PresentationConnections</a></code> so that agents can track
 the number of active connections.</p>
   </ol>
   <h3 class="heading settled" data-level="12.4" id="remote-playback-considerations"><span class="secno">12.4. </span><span class="content">Remote Playback API Considerations</span><a class="self-link" href="#remote-playback-considerations"></a></h3>
   <p>The <a href="https://www.w3.org/TR/remote-playback/#security-and-privacy-considerations">Remote Playback API §security-and-privacy-considerations</a> also state that
messaging between controllers and receivers should also be authenticated and
confidential.</p>
   <p>This consideration is handled by requiring mutual authentication and a
TLS-secured QUIC connection before any remote playback related messages are
exchanged.</p>
   <h3 class="heading settled" data-level="12.5" id="security-mitigations"><span class="secno">12.5. </span><span class="content">Mitigation Strategies</span><a class="self-link" href="#security-mitigations"></a></h3>
   <h4 class="heading settled" data-level="12.5.1" id="local-passive-mitigations"><span class="secno">12.5.1. </span><span class="content">Local passive network attackers</span><a class="self-link" href="#local-passive-mitigations"></a></h4>
   <p>Local passive attackers may attempt to harvest data about user activities and
device capabilities using the Open Screen Protocol.  The main strategy to address
this is data minimization, by only exposing opaque public key fingerprints
before user-mediated authentication takes place.</p>
   <p>Passive attackers may also attempt timing attacks to learn the cryptographic
parameters of the TLS 1.3 QUIC connection.  The application profile for TLS 1.3
mandates constant-time ciphers and TLS 1.3 implementations should use elliptic
curve signing operations that are resistant to side channel attacks.</p>
   <h4 class="heading settled" data-level="12.5.2" id="local-active-mitigations"><span class="secno">12.5.2. </span><span class="content">Local active network attackers</span><a class="self-link" href="#local-active-mitigations"></a></h4>
   <p>Local active attackers may attempt to impersonate a presentation display the
user would normally trust.  The <a href="#authentication">§ 6 Authentication</a> step of the Open Screen
Protocol prevents a man-in-the-middle from impersonating an agent, without
knowledge of a shared secret.  However, it is possible for an attacker to
impersonate an existing, trusted agent or a newly discovered agent that is not
yet authenticated and try to convince the user to authenticate to it.  (Trust in
this context means that a user has completed <a href="#authentication">§ 6 Authentication</a> from their
agent to another agent.)</p>
   <p>This can be addressed through a combination of techniques.  The first is
detecting attempts at impersonation.  Agents should detect the following
situations and flag an agent that meets any of the criteria as a <dfn class="dfn-paneled" data-dfn-type="dfn" data-lt="suspicious agent" data-noexport id="suspicious-agent">suspicious
agent</dfn>:</p>
   <ul>
    <li data-md>
     <p>Agents with distinct IP endpoints whose public key fingerprints collide during
concurrent advertisement.</p>
    <li data-md>
     <p>Untrusted agents whose display name differs from the one previously
advertised under a given public key fingerprint.</p>
    <li data-md>
     <p>Untrusted agents that fail the authentication challenge a certain number of times.</p>
    <li data-md>
     <p>Untrusted agents that advertise a display name that is similar to that from an
already-trusted agent.</p>
    <li data-md>
     <p>Already-trusted agents whose metadata provided through the <a data-link-type="dfn">agent-info</a> message has changed.</p>
   </ul>
   <p>The second is through management of the low-entropy secret during mutual
authentication:</p>
   <ul>
    <li data-md>
     <p>Rotate the low-entropy secret to prevent brute force attacks.</p>
    <li data-md>
     <p>Use an increasing backoff to respond to authentication challenges, also to
prevent brute force attacks.</p>
    <li data-md>
     <p>Use a cryptographically sound source of entropy to generate the shared secret.</p>
   </ul>
   <p>The active attacker may also attempt to disrupt data exchanged over the QUIC
connection by injecting or modifying traffic.  These attacks should be mitigated
by a correct implementation of TLS 1.3.  See Appendix E of <a data-link-type="biblio" href="#biblio-rfc846">[RFC846]</a> for a
detailed security analysis of the TLS 1.3 protocol.</p>
   <h4 class="heading settled" data-level="12.5.3" id="remote-active-mitigations"><span class="secno">12.5.3. </span><span class="content">Remote active network attackers</span><a class="self-link" href="#remote-active-mitigations"></a></h4>
   <p>Unfortunately, we cannot rely on network devices to fully protect OSP agents,
because a misconfigured firewall or NAT could expose a LAN-connected agent to
the broader Internet.  OSP agents should be secure against attack from any
Internet host.</p>
   <p>Advertising agents must set the <code>at</code> field in their mDNS TXT record to protect
themselves from off-LAN attempts to initiate <a href="#authentication">§ 6 Authentication</a>, which result
in user annoyance (display or input of PSK) and potential brute force attacks
against the PSK.</p>
   <h4 class="heading settled" data-level="12.5.4" id="denial-of-service-mitigations"><span class="secno">12.5.4. </span><span class="content">Denial of service</span><a class="self-link" href="#denial-of-service-mitigations"></a></h4>
   <p>It will be difficult to completely prevent denial service of attacks that
originate on the user’s local area network.  OSP agents can refuse new
connections, close connections that receive too many messages, or limit the
number of mDNS records cached from a specific responder in an attempt to allow
existing activities to continue in spite of such an attack.</p>
   <h4 class="heading settled" data-level="12.5.5" id="malicious-input-mitigations"><span class="secno">12.5.5. </span><span class="content">Malicious input</span><a class="self-link" href="#malicious-input-mitigations"></a></h4>
   <p>OSP agents should be robust against malicious input that attempts to compromise
the target device by exploiting parsing vulnerabilities.</p>
   <p>CBOR is intended to be less vulnerable to such attacks relative to alternatives
like JSON and XML.  Still, agents should be thoroughly tested using approaches
like <a href="https://en.wikipedia.org/wiki/Fuzzing">fuzz testing</a>.</p>
   <p>Where possible, OSP agents (including the content rendering components) should
use defense-in-depth techniques like <a href="https://en.wikipedia.org/wiki/Sandbox_(computer_security)">sandboxing</a> to prevent vulnerabilities from gaining access to user data or leading to
persistent exploits.</p>
   <h3 class="heading settled" data-level="12.6" id="security-ui"><span class="secno">12.6. </span><span class="content">User Interface Considerations</span><a class="self-link" href="#security-ui"></a></h3>
   <p>This specification does not make any specific requirements of the security
relevant user interfaces of OSP agents.  However there are important
considerations when designing these user interfaces, as PSK-based authentication
requires users to make informed decisions about which agents to trust.</p>
   <ol>
    <li data-md>
     <p>Before an agent has authenticated another device, the agent should make it
clear that any <code>agent-info</code> or other data from that device has not been
verified by authentication.  (See below for how this applies to DNS-SD
Instance Names.)</p>
    <li data-md>
     <p>A <a data-link-type="dfn" href="#suspicious-agent" id="ref-for-suspicious-agent">suspicious agent</a> should be displayed differently from trusted
agents that are not suspicious, or not displayed at all.</p>
    <li data-md>
     <p>The user interface to present a PSK during authentication should be done in
trusted UI and be difficult to spoof.  It should be clear to the user which
physical device is presenting the PSK.</p>
    <li data-md>
     <p>The user interface to input a PSK during authentication should be done in
trusted UI and be difficult to spoof.</p>
    <li data-md>
     <p>The user should be required to take action to input the PSK, to prevent the
user from blindly clicking through this step.</p>
    <li data-md>
     <p>The user interfaces to render and input a PSK should meet accessibility
guidelines.</p>
   </ol>
   <h4 class="heading settled" data-level="12.6.1" id="instance-names"><span class="secno">12.6.1. </span><span class="content">Instance and Display Names</span><a class="self-link" href="#instance-names"></a></h4>
   <p>Because DNS-SD <a data-link-type="dfn" href="https://tools.ietf.org/html/rfc6763#section-4.1.1" id="ref-for-section-4.1.1①">Instance Names</a> are the primary information that the user
sees prior to authentication, careful presentation of these names is necessary.</p>
   <p>Agents must treat Instance Names as unverified information, and should check
that the Instance Name is a prefix of the display name received through the <a data-link-type="dfn">agent-info</a> message after a successful QUIC connection.  Once an agent has done
this check, it can show the name as a <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="verified-display-name">verified display name</dfn>.</p>
   <p>Agents should show only complete display names to the user, instead of truncated
display names from DNS-SD.  A truncated display name should be verified as above
before being shown in full as a <a data-link-type="dfn" href="#verified-display-name" id="ref-for-verified-display-name">verified display name</a>.</p>
   <div class="note" role="note">
     This means there are three categories of display names that agents should be
capable of handling: 
    <ol>
     <li>Truncated and unverified DNS-SD Instance Names, which should not be shown to the user.
     <li>Complete but unverified DNS-SD Instance Names, which can be shown as
     unverified prior to <a href="#authentication">§ 6 Authentication</a>.
     <li>Verified display names.
    </ol>
   </div>
   <h2 class="heading settled" id="appendix-a"><span class="content">Appendix A: Messages</span><a class="self-link" href="#appendix-a"></a></h2>
   <p>The following messages are defined with <span>CDDL</span>. When integer keys are used, a
comment is appended to the line to indicate the name of the field. Object
definitions in this specification have this unusual syntax to reduce the number
of bytes-on-the-wire, while maintaining a human-readable name for each
key. Integer keys are used instead of object arrays to allow for easy indexing
of optional fields.</p>
   <p>Each root message (one that can be put into a QUIC stream without being enclosed
by another message) has a comment indicating the message type key.</p>
   <p>Smaller numbers should be reserved for message that will be sent more frequently
or are very small or both and larger numbers should be reserved for messages
that are infrequently sent or large or both because smaller type keys encode on
the wire smaller.</p>
   <h2 class="heading settled" id="appendix-b"><span class="content">Appendix B: Message Type Key Ranges</span><a class="self-link" href="#appendix-b"></a></h2>
   <p>The following appendix describes how the range of message type keys is divided.
Legal values are 1 to 2<sup>64</sup>.</p>
   <p>Each type key is encoded as a variable-length integer on the wire of 1, 2, 4 or
8 bytes.  For each wire byte size, 1/4 to 1/2 of the keys are available for
extensions.</p>
   <table>
    <thead>
     <tr>
      <th>Bytes
      <th>Range
      <th>Purpose
    <tbody>
     <tr>
      <td>1
      <td>1 - 48
      <td>Open Screen Protocol
     <tr>
      <td>1
      <td>49 - 63
      <td>Available for extensions
     <tr>
      <td>2
      <td>64 - 8,192
      <td>Open Screen Protocol
     <tr>
      <td>2
      <td>8,193 - 16,383
      <td>Available for extensions
     <tr>
      <td>4
      <td>16,384 - 2<sup>29</sup>
      <td>Reserved for future use
     <tr>
      <td>4
      <td>2<sup>29</sup>+1 - 2<sup>30</sup>-1
      <td>Available for extensions
     <tr>
      <td>8
      <td>>= 2<sup>30</sup>
      <td>Reserved for future use
   </table>
   <p id="back-to-top" role="navigation"><a href="#toc"><abbr title="Back to Top">↑</abbr></a></p>
<script src="https://www.w3.org/scripts/TR/2016/fixup.js"></script>
  </main>
  <h2 class="no-num no-ref heading settled" id="index"><span class="content">Index</span><a class="self-link" href="#index"></a></h2>
  <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="content">Terms defined by this specification</span><a class="self-link" href="#index-defined-here"></a></h3>
  <ul class="index">
   <li><a href="#advertising-agent">advertising agent</a><span>, in §3</span>
   <li><a href="#agent-certificate">agent certificate</a><span>, in §4.2</span>
   <li><a href="#agent-fingerprint">agent fingerprint</a><span>, in §3</span>
   <li><a href="#controller">controller</a><span>, in §1.1</span>
   <li><a href="#display-name">display name</a><span>, in §3</span>
   <li><a href="#listening-agent">listening agent</a><span>, in §3</span>
   <li><a href="#media-receiver">media receiver</a><span>, in §1.1</span>
   <li><a href="#media-sender">media sender</a><span>, in §1.1</span>
   <li><a href="#open-screen-protocol-agent">open screen protocol agent</a><span>, in §1.1</span>
   <li><a href="#open-screen-protocol-agent">osp agent</a><span>, in §1.1</span>
   <li><a href="#receiver">receiver</a><span>, in §1.1</span>
   <li><a href="#suspicious-agent">suspicious agent</a><span>, in §12.5.2</span>
   <li><a href="#verified-display-name">verified display name</a><span>, in §12.6.1</span>
  </ul>
  <aside class="dfn-panel" data-for="term-for-htmlmediaelement">
   <a href="https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement">https://html.spec.whatwg.org/multipage/media.html#htmlmediaelement</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-htmlmediaelement">2.3. Remote Playback API Requirements</a> <a href="#ref-for-htmlmediaelement①">(2)</a> <a href="#ref-for-htmlmediaelement②">(3)</a> <a href="#ref-for-htmlmediaelement③">(4)</a> <a href="#ref-for-htmlmediaelement④">(5)</a>
    <li><a href="#termref-for-">8.1. Remote Playback State and Controls</a>
    <li><a href="#ref-for-htmlmediaelement⑤">8.2. Remote Playback API</a> <a href="#ref-for-htmlmediaelement⑥">(2)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-media-element">
   <a href="https://html.spec.whatwg.org/multipage/media.html#media-element">https://html.spec.whatwg.org/multipage/media.html#media-element</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-media-element">1. Introduction</a>
    <li><a href="#ref-for-media-element①">1.1. Terminology</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dom-window-postmessage">
   <a href="https://html.spec.whatwg.org/multipage/web-messaging.html#dom-window-postmessage">https://html.spec.whatwg.org/multipage/web-messaging.html#dom-window-postmessage</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dom-window-postmessage">12.1.4. Same-Origin Policy Violations</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-attr-source-src">
   <a href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-source-src">https://html.spec.whatwg.org/multipage/embedded-content.html#attr-source-src</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-attr-source-src">8. Remote Playback Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-attr-source-type">
   <a href="https://html.spec.whatwg.org/multipage/embedded-content.html#attr-source-type">https://html.spec.whatwg.org/multipage/embedded-content.html#attr-source-type</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-attr-source-type">8. Remote Playback Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-presentationconnection">
   <a href="https://w3c.github.io/presentation-api/#presentationconnection">https://w3c.github.io/presentation-api/#presentationconnection</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-presentationconnection">2.2. Presentation API Requirements</a> <a href="#ref-for-presentationconnection①">(2)</a>
    <li><a href="#ref-for-presentationconnection②">12.1.4. Same-Origin Policy Violations</a>
    <li><a href="#ref-for-presentationconnection③">12.3. Presentation API Considerations</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-available-presentation-display">
   <a href="https://w3c.github.io/presentation-api/#dfn-available-presentation-display">https://w3c.github.io/presentation-api/#dfn-available-presentation-display</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-available-presentation-display">7. Presentation Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-controlling-user-agent">
   <a href="https://w3c.github.io/presentation-api/#dfn-controlling-user-agent">https://w3c.github.io/presentation-api/#dfn-controlling-user-agent</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-controlling-user-agent">1.1. Terminology</a>
    <li><a href="#ref-for-dfn-controlling-user-agent①">7.1. Presentation API</a> <a href="#ref-for-dfn-controlling-user-agent②">(2)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-presentation">
   <a href="https://w3c.github.io/presentation-api/#dfn-presentation">https://w3c.github.io/presentation-api/#dfn-presentation</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-presentation">1.1. Terminology</a>
    <li><a href="#ref-for-dfn-presentation①">2.2. Presentation API Requirements</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-presentation-id">
   <a href="https://w3c.github.io/presentation-api/#dfn-presentation-id">https://w3c.github.io/presentation-api/#dfn-presentation-id</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-presentation-id">2.2. Presentation API Requirements</a> <a href="#ref-for-dfn-presentation-id①">(2)</a> <a href="#ref-for-dfn-presentation-id②">(3)</a>
    <li><a href="#ref-for-dfn-presentation-id③">12.1.4. Same-Origin Policy Violations</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-presentation-request-url">
   <a href="https://w3c.github.io/presentation-api/#dfn-presentation-request-url">https://w3c.github.io/presentation-api/#dfn-presentation-request-url</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-presentation-request-url">2.2. Presentation API Requirements</a> <a href="#ref-for-dfn-presentation-request-url①">(2)</a> <a href="#ref-for-dfn-presentation-request-url②">(3)</a> <a href="#ref-for-dfn-presentation-request-url③">(4)</a>
    <li><a href="#ref-for-dfn-presentation-request-url④">7. Presentation Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-receiving-user-agent">
   <a href="https://w3c.github.io/presentation-api/#dfn-receiving-user-agent">https://w3c.github.io/presentation-api/#dfn-receiving-user-agent</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-receiving-user-agent">1.1. Terminology</a>
    <li><a href="#ref-for-dfn-receiving-user-agent①">7.1. Presentation API</a> <a href="#ref-for-dfn-receiving-user-agent②">(2)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-19.19">
   <a href="https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-19.19">https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-19.19</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-19.19">5. Messages delivery using CBOR and QUIC streams</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-18">
   <a href="https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-18">https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-18</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-18">4.3. Metadata Discovery</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-16">
   <a href="https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-16">https://tools.ietf.org/html/draft-ietf-quic-transport-23#section-16</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-16">5. Messages delivery using CBOR and QUIC streams</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-availability-sources-set">
   <a href="https://w3c.github.io/remote-playback/#dfn-availability-sources-set">https://w3c.github.io/remote-playback/#dfn-availability-sources-set</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-availability-sources-set">8.2. Remote Playback API</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-compatible-remote-playback-device">
   <a href="https://w3c.github.io/remote-playback/#dfn-compatible-remote-playback-device">https://w3c.github.io/remote-playback/#dfn-compatible-remote-playback-device</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-compatible-remote-playback-device">8. Remote Playback Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-initiate-remote-playback">
   <a href="https://w3c.github.io/remote-playback/#dfn-initiate-remote-playback">https://w3c.github.io/remote-playback/#dfn-initiate-remote-playback</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-initiate-remote-playback">2.3. Remote Playback API Requirements</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-media-element-state">
   <a href="https://w3c.github.io/remote-playback/#dfn-media-element-state">https://w3c.github.io/remote-playback/#dfn-media-element-state</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-media-element-state">2.3. Remote Playback API Requirements</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-media-resources">
   <a href="https://w3c.github.io/remote-playback/#dfn-media-resources">https://w3c.github.io/remote-playback/#dfn-media-resources</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-media-resources">8. Remote Playback Protocol</a> <a href="#ref-for-dfn-media-resources①">(2)</a> <a href="#ref-for-dfn-media-resources②">(3)</a> <a href="#ref-for-dfn-media-resources③">(4)</a>
    <li><a href="#ref-for-dfn-media-resources④">8.1. Remote Playback State and Controls</a> <a href="#ref-for-dfn-media-resources⑤">(2)</a> <a href="#ref-for-dfn-media-resources⑥">(3)</a> <a href="#ref-for-dfn-media-resources⑦">(4)</a> <a href="#ref-for-dfn-media-resources⑧">(5)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-remote-playback-devices">
   <a href="https://w3c.github.io/remote-playback/#dfn-remote-playback-devices">https://w3c.github.io/remote-playback/#dfn-remote-playback-devices</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-remote-playback-devices">1.1. Terminology</a>
    <li><a href="#ref-for-dfn-remote-playback-devices①">8.2. Remote Playback API</a> <a href="#ref-for-dfn-remote-playback-devices②">(2)</a> <a href="#ref-for-dfn-remote-playback-devices③">(3)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dfn-remote-playback-source">
   <a href="https://w3c.github.io/remote-playback/#dfn-remote-playback-source">https://w3c.github.io/remote-playback/#dfn-remote-playback-source</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dfn-remote-playback-source">8.2. Remote Playback API</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-4.4">
   <a href="https://tools.ietf.org/html/rfc4122#section-4.4">https://tools.ietf.org/html/rfc4122#section-4.4</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-4.4">8. Remote Playback Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-2">
   <a href="https://tools.ietf.org/html/rfc5646#section-2">https://tools.ietf.org/html/rfc5646#section-2</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-2">4.3. Metadata Discovery</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-3">
   <a href="https://tools.ietf.org/html/rfc6381#section-3">https://tools.ietf.org/html/rfc6381#section-3</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-3">9.1. Streaming Protocol Capabilities</a>
    <li><a href="#ref-for-section-3①">9.2. Sessions</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-9">
   <a href="https://tools.ietf.org/html/rfc6762#section-9">https://tools.ietf.org/html/rfc6762#section-9</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-9">3. Discovery with mDNS</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-4.1.1">
   <a href="https://tools.ietf.org/html/rfc6763#section-4.1.1">https://tools.ietf.org/html/rfc6763#section-4.1.1</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-4.1.1">3. Discovery with mDNS</a>
    <li><a href="#ref-for-section-4.1.1①">12.6.1. Instance and Display Names</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-7">
   <a href="https://tools.ietf.org/html/rfc6763#section-7">https://tools.ietf.org/html/rfc6763#section-7</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-7">3. Discovery with mDNS</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-5">
   <a href="https://tools.ietf.org/html/rfc8122#section-5">https://tools.ietf.org/html/rfc8122#section-5</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-5">3. Discovery with mDNS</a> <a href="#ref-for-section-5①">(2)</a> <a href="#ref-for-section-5②">(3)</a> <a href="#ref-for-section-5③">(4)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-5">
   <a href="https://tools.ietf.org/html/rfc8122#section-5">https://tools.ietf.org/html/rfc8122#section-5</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-5">3. Discovery with mDNS</a> <a href="#ref-for-section-5①">(2)</a> <a href="#ref-for-section-5②">(3)</a> <a href="#ref-for-section-5③">(4)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-5">
   <a href="https://tools.ietf.org/html/rfc8122#section-5">https://tools.ietf.org/html/rfc8122#section-5</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-5">3. Discovery with mDNS</a> <a href="#ref-for-section-5①">(2)</a> <a href="#ref-for-section-5②">(3)</a> <a href="#ref-for-section-5③">(4)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-section-5">
   <a href="https://tools.ietf.org/html/rfc8122#section-5">https://tools.ietf.org/html/rfc8122#section-5</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-section-5">3. Discovery with mDNS</a> <a href="#ref-for-section-5①">(2)</a> <a href="#ref-for-section-5②">(3)</a> <a href="#ref-for-section-5③">(4)</a>
   </ul>
  </aside>
  <h3 class="no-num no-ref heading settled" id="index-defined-elsewhere"><span class="content">Terms defined by reference</span><a class="self-link" href="#index-defined-elsewhere"></a></h3>
  <ul class="index">
   <li>
    <a data-link-type="biblio">[HTML]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-htmlmediaelement" style="color:initial">HTMLMediaElement</span>
     <li><span class="dfn-paneled" id="term-for-media-element" style="color:initial">media elements</span>
     <li><span class="dfn-paneled" id="term-for-dom-window-postmessage" style="color:initial">postMessage(message, targetOrigin, transfer)</span>
     <li><span class="dfn-paneled" id="term-for-attr-source-src" style="color:initial">src</span>
     <li><span class="dfn-paneled" id="term-for-attr-source-type" style="color:initial">type</span>
    </ul>
   <li>
    <a data-link-type="biblio">[PRESENTATION-API]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-presentationconnection" style="color:initial">PresentationConnection</span>
     <li><span class="dfn-paneled" id="term-for-dfn-available-presentation-display" style="color:initial">available presentation display</span>
     <li><span class="dfn-paneled" id="term-for-dfn-controlling-user-agent" style="color:initial">controlling user agent</span>
     <li><span class="dfn-paneled" id="term-for-dfn-presentation" style="color:initial">presentation</span>
     <li><span class="dfn-paneled" id="term-for-dfn-presentation-id" style="color:initial">presentation id</span>
     <li><span class="dfn-paneled" id="term-for-dfn-presentation-request-url" style="color:initial">presentation request url</span>
     <li><span class="dfn-paneled" id="term-for-dfn-receiving-user-agent" style="color:initial">receiving user agent</span>
    </ul>
   <li>
    <a data-link-type="biblio">[quic]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-section-19.19" style="color:initial">connection_close frames</span>
     <li><span class="dfn-paneled" id="term-for-section-18" style="color:initial">transport parameter encoding</span>
     <li><span class="dfn-paneled" id="term-for-section-16" style="color:initial">variable-length integer encoding</span>
    </ul>
   <li>
    <a data-link-type="biblio">[REMOTE-PLAYBACK]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-dfn-availability-sources-set" style="color:initial">availability sources set</span>
     <li><span class="dfn-paneled" id="term-for-dfn-compatible-remote-playback-device" style="color:initial">compatible remote playback device</span>
     <li><span class="dfn-paneled" id="term-for-dfn-initiate-remote-playback" style="color:initial">initiate remote playback</span>
     <li><span class="dfn-paneled" id="term-for-dfn-media-element-state" style="color:initial">media element state</span>
     <li><span class="dfn-paneled" id="term-for-dfn-media-resources" style="color:initial">media resources</span>
     <li><span class="dfn-paneled" id="term-for-dfn-remote-playback-devices" style="color:initial">remote playback devices</span>
     <li><span class="dfn-paneled" id="term-for-dfn-remote-playback-source" style="color:initial">remote playback source</span>
    </ul>
   <li>
    <a data-link-type="biblio">[rfc4122]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-section-4.4" style="color:initial">uuid</span>
    </ul>
   <li>
    <a data-link-type="biblio">[rfc5646]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-section-2" style="color:initial">language tag</span>
    </ul>
   <li>
    <a data-link-type="biblio">[rfc6381]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-section-3" style="color:initial">codecs parameter</span>
    </ul>
   <li>
    <a data-link-type="biblio">[RFC6762]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-section-9" style="color:initial">conflict resolution</span>
    </ul>
   <li>
    <a data-link-type="biblio">[RFC6763]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-section-4.1.1" style="color:initial">instance name</span>
     <li><span class="dfn-paneled" id="term-for-section-7" style="color:initial">service name</span>
    </ul>
   <li>
    <a data-link-type="biblio">[rfc8122]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-section-5" style="color:initial">md2</span>
     <li><span class="dfn-paneled" id="term-for-section-5①" style="color:initial">md5</span>
     <li><span class="dfn-paneled" id="term-for-section-5②" style="color:initial">sha-256</span>
     <li><span class="dfn-paneled" id="term-for-section-5③" style="color:initial">sha-512</span>
    </ul>
  </ul>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="normative"><span class="content">Normative References</span><a class="self-link" href="#normative"></a></h3>
  <dl>
   <dt id="biblio-html">[HTML]
   <dd>Anne van Kesteren; et al. <a href="https://html.spec.whatwg.org/multipage/">HTML Standard</a>. Living Standard. URL: <a href="https://html.spec.whatwg.org/multipage/">https://html.spec.whatwg.org/multipage/</a>
   <dt id="biblio-presentation-api">[PRESENTATION-API]
   <dd>Mark Foltz; Dominik Röttsches. <a href="https://www.w3.org/TR/presentation-api/">Presentation API</a>. 1 June 2017. CR. URL: <a href="https://www.w3.org/TR/presentation-api/">https://www.w3.org/TR/presentation-api/</a>
   <dt id="biblio-remote-playback">[REMOTE-PLAYBACK]
   <dd>Mounir Lamouri; Anton Vayvod. <a href="https://www.w3.org/TR/remote-playback/">Remote Playback API</a>. 19 October 2017. CR. URL: <a href="https://www.w3.org/TR/remote-playback/">https://www.w3.org/TR/remote-playback/</a>
   <dt id="biblio-rfc5122">[RFC5122]
   <dd>P. Saint-Andre. <a href="https://tools.ietf.org/html/rfc5122">Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)</a>. February 2008. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc5122">https://tools.ietf.org/html/rfc5122</a>
   <dt id="biblio-rfc5280">[RFC5280]
   <dd>D. Cooper; et al. <a href="https://tools.ietf.org/html/rfc5280">Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile</a>. May 2008. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc5280">https://tools.ietf.org/html/rfc5280</a>
   <dt id="biblio-rfc5646">[RFC5646]
   <dd>A. Phillips, Ed.; M. Davis, Ed.. <a href="https://tools.ietf.org/html/rfc5646">Tags for Identifying Languages</a>. September 2009. Best Current Practice. URL: <a href="https://tools.ietf.org/html/rfc5646">https://tools.ietf.org/html/rfc5646</a>
   <dt id="biblio-rfc6381">[RFC6381]
   <dd>R. Gellens; D. Singer; P. Frojdh. <a href="https://tools.ietf.org/html/rfc6381">The 'Codecs' and 'Profiles' Parameters for "Bucket" Media Types</a>. August 2011. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc6381">https://tools.ietf.org/html/rfc6381</a>
   <dt id="biblio-rfc6762">[RFC6762]
   <dd>S. Cheshire; M. Krochmal. <a href="https://tools.ietf.org/html/rfc6762">Multicast DNS</a>. February 2013. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc6762">https://tools.ietf.org/html/rfc6762</a>
   <dt id="biblio-rfc6763">[RFC6763]
   <dd>S. Cheshire; M. Krochmal. <a href="https://tools.ietf.org/html/rfc6763">DNS-Based Service Discovery</a>. February 2013. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc6763">https://tools.ietf.org/html/rfc6763</a>
   <dt id="biblio-rfc7049">[RFC7049]
   <dd>C. Bormann; P. Hoffman. <a href="https://tools.ietf.org/html/rfc7049">Concise Binary Object Representation (CBOR)</a>. October 2013. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc7049">https://tools.ietf.org/html/rfc7049</a>
   <dt id="biblio-rfc7301">[RFC7301]
   <dd>S. Friedl; et al. <a href="https://tools.ietf.org/html/rfc7301">Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension</a>. July 2014. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc7301">https://tools.ietf.org/html/rfc7301</a>
   <dt id="biblio-rfc8122">[RFC8122]
   <dd>J. Lennox; C. Holmberg. <a href="https://tools.ietf.org/html/rfc8122">Connection-Oriented Media Transport over the Transport Layer Security (TLS) Protocol in the Session Description Protocol (SDP)</a>. March 2017. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc8122">https://tools.ietf.org/html/rfc8122</a>
   <dt id="biblio-rfc8446">[RFC8446]
   <dd>E. Rescorla. <a href="https://tools.ietf.org/html/rfc8446">The Transport Layer Security (TLS) Protocol Version 1.3</a>. August 2018. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc8446">https://tools.ietf.org/html/rfc8446</a>
   <dt id="biblio-rfc8466">[RFC8466]
   <dd>B. Wen; et al. <a href="https://tools.ietf.org/html/rfc8466">A YANG Data Model for Layer 2 Virtual Private Network (L2VPN) Service Delivery</a>. October 2018. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc8466">https://tools.ietf.org/html/rfc8466</a>
  </dl>
  <h3 class="no-num no-ref heading settled" id="informative"><span class="content">Informative References</span><a class="self-link" href="#informative"></a></h3>
  <dl>
   <dt id="biblio-rfc4122">[RFC4122]
   <dd>P. Leach; M. Mealling; R. Salz. <a href="https://tools.ietf.org/html/rfc4122">A Universally Unique IDentifier (UUID) URN Namespace</a>. July 2005. Proposed Standard. URL: <a href="https://tools.ietf.org/html/rfc4122">https://tools.ietf.org/html/rfc4122</a>
   <dt id="biblio-rfc846">[RFC846]
   <dd>A. Westine; D. Smallberg; J. Postel. <a href="https://tools.ietf.org/html/rfc847">Summary of Smallberg surveys</a>. February 1983. Unknown. URL: <a href="https://tools.ietf.org/html/rfc847">https://tools.ietf.org/html/rfc847</a>
   <dt id="biblio-security-privacy-questionnaire">[SECURITY-PRIVACY-QUESTIONNAIRE]
   <dd>Lukasz Olejnik; Jason Novak. <a href="https://www.w3.org/TR/security-privacy-questionnaire/">Self-Review Questionnaire: Security and Privacy</a>. 23 May 2019. NOTE. URL: <a href="https://www.w3.org/TR/security-privacy-questionnaire/">https://www.w3.org/TR/security-privacy-questionnaire/</a>
  </dl>
  <h2 class="no-num no-ref heading settled" id="issues-index"><span class="content">Issues Index</span><a class="self-link" href="#issues-index"></a></h2>
  <div style="counter-reset:issue">
   <div class="issue"> Define suspend and resume behavior for discovery protocol. <a href="https://github.com/w3c/openscreenprotocol/issues/107">&lt;https://github.com/w3c/openscreenprotocol/issues/107></a><a href="#issue-56c2cd35"> ↵ </a></div>
   <div class="issue"> Add examples of sample mDNS records.<a href="#issue-49bdd4e6"> ↵ </a></div>
   <div class="issue"> Register ALPN with IANA. <a href="https://github.com/w3c/openscreenprotocol/issues/228">&lt;https://github.com/w3c/openscreenprotocol/issues/228></a><a href="#issue-808efb48"> ↵ </a></div>
   <div class="issue"> Determine if there is an advantage to session resumption outside of
early data. If we allow session resumption, do we allow early data too? <a href="https://github.com/w3c/openscreenprotocol/issues/220">&lt;https://github.com/w3c/openscreenprotocol/issues/220></a><a href="#issue-eb53583c"> ↵ </a></div>
   <div class="issue"> Do agents need to support the Cookies extension (used in
HelloRetryRequest)? <a href="https://github.com/w3c/openscreenprotocol/issues/219">&lt;https://github.com/w3c/openscreenprotocol/issues/219></a><a href="#issue-983764c9"> ↵ </a></div>
   <div class="issue"> Make recommendations for cipher and signature algorithm preference
list based on hardware characteristics of agents. <a href="https://github.com/w3c/openscreenprotocol/issues/218">&lt;https://github.com/w3c/openscreenprotocol/issues/218></a><a href="#issue-08dfa2ca"> ↵ </a></div>
   <div class="issue"> Define suspend and resume behavior for connection protocol. <a href="https://github.com/w3c/openscreenprotocol/issues/108">&lt;https://github.com/w3c/openscreenprotocol/issues/108></a><a href="#issue-e0955a17"> ↵ </a></div>
   <div class="issue"> What do "client" and "server" mean here?<a href="#issue-492f86ab"> ↵ </a></div>
   <div class="issue"> Once the Presentation API has text about
reconnecting via an implementation specific mechanism, quote that here and map
it to a message. <a href="https://github.com/w3c/presentation-api/issues/471">&lt;https://github.com/w3c/presentation-api/issues/471></a><a href="#issue-733afe74"> ↵ </a></div>
   <div class="issue"> Refinements to Remote Playback protocol. <a href="https://github.com/w3c/openscreenprotocol/issues/159">&lt;https://github.com/w3c/openscreenprotocol/issues/159></a><a href="#issue-649c173f"> ↵ </a></div>
   <div class="issue"> Remote Playback HTTP headers. <a href="https://github.com/w3c/openscreenprotocol/issues/146">&lt;https://github.com/w3c/openscreenprotocol/issues/146></a><a href="#issue-9145071e"> ↵ </a></div>
   <div class="issue"> Fate of metadata / authentication history when clearing browsing data. <a href="https://github.com/w3c/openscreenprotocol/issues/132">&lt;https://github.com/w3c/openscreenprotocol/issues/132></a><a href="#issue-8bf4aa9f"> ↵ </a></div>
  </div>
  <aside class="dfn-panel" data-for="open-screen-protocol-agent">
   <b><a href="#open-screen-protocol-agent">#open-screen-protocol-agent</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-open-screen-protocol-agent">2.1. General Requirements</a>
    <li><a href="#ref-for-open-screen-protocol-agent①">3. Discovery with mDNS</a>
    <li><a href="#ref-for-open-screen-protocol-agent②">4.1. TLS 1.3</a>
    <li><a href="#ref-for-open-screen-protocol-agent③">5. Messages delivery using CBOR and QUIC streams</a>
    <li><a href="#ref-for-open-screen-protocol-agent④">6. Authentication</a>
    <li><a href="#ref-for-open-screen-protocol-agent⑤">7.1. Presentation API</a> <a href="#ref-for-open-screen-protocol-agent⑥">(2)</a>
    <li><a href="#ref-for-open-screen-protocol-agent⑦">8.2. Remote Playback API</a> <a href="#ref-for-open-screen-protocol-agent⑧">(2)</a>
    <li><a href="#ref-for-open-screen-protocol-agent⑨">9. Streaming Protocol</a>
    <li><a href="#ref-for-open-screen-protocol-agent①⓪">11. Protocol Extensions</a>
    <li><a href="#ref-for-open-screen-protocol-agent①①">12. Security and Privacy</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="controller">
   <b><a href="#controller">#controller</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-controller">1.1. Terminology</a>
    <li><a href="#ref-for-controller①">2.2. Presentation API Requirements</a>
    <li><a href="#ref-for-controller②">2.3. Remote Playback API Requirements</a>
    <li><a href="#ref-for-controller③">7.1. Presentation API</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="receiver">
   <b><a href="#receiver">#receiver</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-receiver">1.1. Terminology</a>
    <li><a href="#ref-for-receiver①">2.2. Presentation API Requirements</a>
    <li><a href="#ref-for-receiver②">2.3. Remote Playback API Requirements</a>
    <li><a href="#ref-for-receiver③">7. Presentation Protocol</a>
    <li><a href="#ref-for-receiver④">8.2. Remote Playback API</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="media-sender">
   <b><a href="#media-sender">#media-sender</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-media-sender">9. Streaming Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="media-receiver">
   <b><a href="#media-receiver">#media-receiver</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-media-receiver">9. Streaming Protocol</a>
    <li><a href="#ref-for-media-receiver①">9.3. Audio</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="advertising-agent">
   <b><a href="#advertising-agent">#advertising-agent</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-advertising-agent">2.4. Non-Functional Requirements</a>
    <li><a href="#ref-for-advertising-agent①">4. Transport and metadata discovery with QUIC</a>
    <li><a href="#ref-for-advertising-agent②">4.2. Agent Certificates</a>
    <li><a href="#ref-for-advertising-agent③">6. Authentication</a>
    <li><a href="#ref-for-advertising-agent④">7.1. Presentation API</a>
    <li><a href="#ref-for-advertising-agent⑤">8.2. Remote Playback API</a>
    <li><a href="#ref-for-advertising-agent⑥">9. Streaming Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="display-name">
   <b><a href="#display-name">#display-name</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-display-name">12.2.1. Personally Identifiable Information &amp; High-Value Data</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="listening-agent">
   <b><a href="#listening-agent">#listening-agent</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-listening-agent">2.4. Non-Functional Requirements</a>
    <li><a href="#ref-for-listening-agent①">4. Transport and metadata discovery with QUIC</a>
    <li><a href="#ref-for-listening-agent②">4.2. Agent Certificates</a>
    <li><a href="#ref-for-listening-agent③">7.1. Presentation API</a>
    <li><a href="#ref-for-listening-agent④">8.2. Remote Playback API</a>
    <li><a href="#ref-for-listening-agent⑤">9. Streaming Protocol</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="agent-fingerprint">
   <b><a href="#agent-fingerprint">#agent-fingerprint</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-agent-fingerprint">4.1. TLS 1.3</a>
    <li><a href="#ref-for-agent-fingerprint①">4.2. Agent Certificates</a>
    <li><a href="#ref-for-agent-fingerprint②">6.1. Authentication with SPAKE2</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="agent-certificate">
   <b><a href="#agent-certificate">#agent-certificate</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-agent-certificate">3. Discovery with mDNS</a>
    <li><a href="#ref-for-agent-certificate①">4.2. Agent Certificates</a> <a href="#ref-for-agent-certificate②">(2)</a> <a href="#ref-for-agent-certificate③">(3)</a> <a href="#ref-for-agent-certificate④">(4)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="suspicious-agent">
   <b><a href="#suspicious-agent">#suspicious-agent</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-suspicious-agent">12.6. User Interface Considerations</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="verified-display-name">
   <b><a href="#verified-display-name">#verified-display-name</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-verified-display-name">12.6.1. Instance and Display Names</a>
   </ul>
  </aside>
<script>/* script-dfn-panel */

document.body.addEventListener("click", function(e) {
    var queryAll = function(sel) { return [].slice.call(document.querySelectorAll(sel)); }
    // Find the dfn element or panel, if any, that was clicked on.
    var el = e.target;
    var target;
    var hitALink = false;
    while(el.parentElement) {
        if(el.tagName == "A") {
            // Clicking on a link in a <dfn> shouldn't summon the panel
            hitALink = true;
        }
        if(el.classList.contains("dfn-paneled")) {
            target = "dfn";
            break;
        }
        if(el.classList.contains("dfn-panel")) {
            target = "dfn-panel";
            break;
        }
        el = el.parentElement;
    }
    if(target != "dfn-panel") {
        // Turn off any currently "on" or "activated" panels.
        queryAll(".dfn-panel.on, .dfn-panel.activated").forEach(function(el){
            el.classList.remove("on");
            el.classList.remove("activated");
        });
    }
    if(target == "dfn" && !hitALink) {
        // open the panel
        var dfnPanel = document.querySelector(".dfn-panel[data-for='" + el.id + "']");
        if(dfnPanel) {
            dfnPanel.classList.add("on");
            var rect = el.getBoundingClientRect();
            dfnPanel.style.left = window.scrollX + rect.right + 5 + "px";
            dfnPanel.style.top = window.scrollY + rect.top + "px";
            var panelRect = dfnPanel.getBoundingClientRect();
            var panelWidth = panelRect.right - panelRect.left;
            if(panelRect.right > document.body.scrollWidth && (rect.left - (panelWidth + 5)) > 0) {
                // Reposition, because the panel is overflowing
                dfnPanel.style.left = window.scrollX + rect.left - (panelWidth + 5) + "px";
            }
        } else {
            console.log("Couldn't find .dfn-panel[data-for='" + el.id + "']");
        }
    } else if(target == "dfn-panel") {
        // Switch it to "activated" state, which pins it.
        el.classList.add("activated");
        el.style.left = null;
        el.style.top = null;
    }

});
</script>